diff options
Diffstat (limited to 'src/bbcode.cpp')
| -rw-r--r-- | src/bbcode.cpp | 236 |
1 files changed, 131 insertions, 105 deletions
diff --git a/src/bbcode.cpp b/src/bbcode.cpp index e143909f..f1a3d375 100644 --- a/src/bbcode.cpp +++ b/src/bbcode.cpp @@ -18,29 +18,32 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. */ #include "bbcode.h" -#include <log.h> #include <QRegularExpression> +#include <log.h> #include <map> -namespace BBCode { +namespace BBCode +{ namespace log = MOBase::log; -class BBCodeMap { +class BBCodeMap +{ - typedef std::map<QString, std::pair<QRegularExpression, QString> > TagMap; + typedef std::map<QString, std::pair<QRegularExpression, QString>> TagMap; public: - - static BBCodeMap &instance() { + static BBCodeMap& instance() + { static BBCodeMap s_Instance; return s_Instance; } - QString convertTag(QString input, int &length) + QString convertTag(QString input, int& length) { // extract the tag name - auto match = m_TagNameExp.match(input, 1, QRegularExpression::NormalMatch, QRegularExpression::AnchoredMatchOption); + auto match = m_TagNameExp.match(input, 1, QRegularExpression::NormalMatch, + QRegularExpression::AnchoredMatchOption); QString tagName = match.captured(0).toLower(); TagMap::iterator tagIter = m_TagMap.find(tagName); if (tagIter != m_TagMap.end()) { @@ -49,25 +52,31 @@ public: tagName.chop(1); } - int closeTagPos = 0; - int nextTagPos = 0; + int closeTagPos = 0; + int nextTagPos = 0; int nextTagSearchIndex = input.indexOf("]"); - int closeTagLength = 0; + int closeTagLength = 0; if (tagName == "*") { // ends at the next bullet point - closeTagPos = input.indexOf(QRegularExpression("(\\[\\*\\]|</ul>)", QRegularExpression::CaseInsensitiveOption), 3); - // leave closeTagLength at 0 because we don't want to "eat" the next bullet point + closeTagPos = + input.indexOf(QRegularExpression("(\\[\\*\\]|</ul>)", + QRegularExpression::CaseInsensitiveOption), + 3); + // leave closeTagLength at 0 because we don't want to "eat" the next bullet + // point } else if (tagName == "line") { // ends immediately after the tag closeTagPos = 6; // leave closeTagLength at 0 because there is no close tag to skip over } else { - QRegularExpression nextTag(QString("\\[%1[=\\]]?").arg(tagName), QRegularExpression::CaseInsensitiveOption); + QRegularExpression nextTag(QString("\\[%1[=\\]]?").arg(tagName), + QRegularExpression::CaseInsensitiveOption); QString closeTag = QString("[/%1]").arg(tagName); - closeTagPos = input.indexOf(closeTag, 0, Qt::CaseInsensitive); - nextTagPos = nextTag.match(input, nextTagSearchIndex).capturedStart(0); + closeTagPos = input.indexOf(closeTag, 0, Qt::CaseInsensitive); + nextTagPos = nextTag.match(input, nextTagSearchIndex).capturedStart(0); while (nextTagPos != -1 && closeTagPos != -1 && nextTagPos < closeTagPos) { - closeTagPos = input.indexOf(closeTag, closeTagPos + closeTag.size(), Qt::CaseInsensitive); + closeTagPos = input.indexOf(closeTag, closeTagPos + closeTag.size(), + Qt::CaseInsensitive); nextTagSearchIndex = input.indexOf("]", nextTagPos); nextTagPos = nextTag.match(input, nextTagSearchIndex).capturedStart(0); } @@ -80,23 +89,28 @@ public: } if (closeTagPos > -1) { - length = closeTagPos + closeTagLength; + length = closeTagPos + closeTagLength; QString temp = input.mid(0, length); - tagIter->second.first.setPatternOptions(QRegularExpression::PatternOption::DotMatchesEverythingOption); + tagIter->second.first.setPatternOptions( + QRegularExpression::PatternOption::DotMatchesEverythingOption); auto match = tagIter->second.first.match(temp); if (match.hasMatch()) { if (tagIter->second.second.isEmpty()) { if (tagName == "color") { - QString color = match.captured(1); + QString color = match.captured(1); QString content = match.captured(2); if (color.at(0) == '#') { - return temp.replace(tagIter->second.first, QString("<font style=\"color: %1;\">%2</font>").arg(color, content)); + return temp.replace(tagIter->second.first, + QString("<font style=\"color: %1;\">%2</font>") + .arg(color, content)); } else { auto colIter = m_ColorMap.find(color.toLower()); if (colIter != m_ColorMap.end()) { color = colIter->second; } - return temp.replace(tagIter->second.first, QString("<font style=\"color: #%1;\">%2</font>").arg(color, content)); + return temp.replace(tagIter->second.first, + QString("<font style=\"color: #%1;\">%2</font>") + .arg(color, content)); } } else { log::warn("don't know how to deal with tag {}", tagName); @@ -123,89 +137,105 @@ public: } private: - BBCodeMap() - : m_TagNameExp("[a-zA-Z*]*=?") + BBCodeMap() : m_TagNameExp("[a-zA-Z*]*=?") { - m_TagMap["b"] = std::make_pair(QRegularExpression("\\[b\\](.*)\\[/b\\]"), - "<b>\\1</b>"); - m_TagMap["i"] = std::make_pair(QRegularExpression("\\[i\\](.*)\\[/i\\]"), - "<i>\\1</i>"); - m_TagMap["u"] = std::make_pair(QRegularExpression("\\[u\\](.*)\\[/u\\]"), - "<u>\\1</u>"); - m_TagMap["s"] = std::make_pair(QRegularExpression("\\[s\\](.*)\\[/s\\]"), - "<s>\\1</s>"); - m_TagMap["sub"] = std::make_pair(QRegularExpression("\\[sub\\](.*)\\[/sub\\]"), - "<sub>\\1</sub>"); - m_TagMap["sup"] = std::make_pair(QRegularExpression("\\[sup\\](.*)\\[/sup\\]"), - "<sup>\\1</sup>"); - m_TagMap["size="] = std::make_pair(QRegularExpression("\\[size=([^\\]]*)\\](.*)\\[/size\\]"), - "<font size=\"\\1\">\\2</font>"); - m_TagMap["color="] = std::make_pair(QRegularExpression("\\[color=([^\\]]*)\\](.*)\\[/color\\]"), - ""); - m_TagMap["font="] = std::make_pair(QRegularExpression("\\[font=([^\\]]*)\\](.*)\\[/font\\]"), - "<font style=\"font-family: \\1;\">\\2</font>"); - m_TagMap["center"] = std::make_pair(QRegularExpression("\\[center\\](.*)\\[/center\\]"), - "<div align=\"center\">\\1</div>"); - m_TagMap["right"] = std::make_pair(QRegularExpression("\\[right\\](.*)\\[/right\\]"), - "<div align=\"right\">\\1</div>"); - m_TagMap["quote"] = std::make_pair(QRegularExpression("\\[quote\\](.*)\\[/quote\\]"), - "<figure class=\"quote\"><blockquote>\\1</blockquote></figure>"); - m_TagMap["quote="] = std::make_pair(QRegularExpression("\\[quote=([^\\]]*)\\](.*)\\[/quote\\]"), - "<figure class=\"quote\"><blockquote>\\2</blockquote></figure>"); - m_TagMap["spoiler"] = std::make_pair(QRegularExpression("\\[spoiler\\](.*)\\[/spoiler\\]"), - "<details><summary>Spoiler: <div class=\"bbc_spoiler_show\">Show</div></summary><div class=\"spoiler_content\">\\1</div></details>"); - m_TagMap["code"] = std::make_pair(QRegularExpression("\\[code\\](.*)\\[/code\\]"), - "<code>\\1</code>"); - m_TagMap["heading"]= std::make_pair(QRegularExpression("\\[heading\\](.*)\\[/heading\\]"), - "<h2><strong>\\1</strong></h2>"); - m_TagMap["line"] = std::make_pair(QRegularExpression("\\[line\\]"), - "<hr>"); + m_TagMap["b"] = + std::make_pair(QRegularExpression("\\[b\\](.*)\\[/b\\]"), "<b>\\1</b>"); + m_TagMap["i"] = + std::make_pair(QRegularExpression("\\[i\\](.*)\\[/i\\]"), "<i>\\1</i>"); + m_TagMap["u"] = + std::make_pair(QRegularExpression("\\[u\\](.*)\\[/u\\]"), "<u>\\1</u>"); + m_TagMap["s"] = + std::make_pair(QRegularExpression("\\[s\\](.*)\\[/s\\]"), "<s>\\1</s>"); + m_TagMap["sub"] = + std::make_pair(QRegularExpression("\\[sub\\](.*)\\[/sub\\]"), "<sub>\\1</sub>"); + m_TagMap["sup"] = + std::make_pair(QRegularExpression("\\[sup\\](.*)\\[/sup\\]"), "<sup>\\1</sup>"); + m_TagMap["size="] = + std::make_pair(QRegularExpression("\\[size=([^\\]]*)\\](.*)\\[/size\\]"), + "<font size=\"\\1\">\\2</font>"); + m_TagMap["color="] = + std::make_pair(QRegularExpression("\\[color=([^\\]]*)\\](.*)\\[/color\\]"), ""); + m_TagMap["font="] = + std::make_pair(QRegularExpression("\\[font=([^\\]]*)\\](.*)\\[/font\\]"), + "<font style=\"font-family: \\1;\">\\2</font>"); + m_TagMap["center"] = + std::make_pair(QRegularExpression("\\[center\\](.*)\\[/center\\]"), + "<div align=\"center\">\\1</div>"); + m_TagMap["right"] = + std::make_pair(QRegularExpression("\\[right\\](.*)\\[/right\\]"), + "<div align=\"right\">\\1</div>"); + m_TagMap["quote"] = + std::make_pair(QRegularExpression("\\[quote\\](.*)\\[/quote\\]"), + "<figure class=\"quote\"><blockquote>\\1</blockquote></figure>"); + m_TagMap["quote="] = + std::make_pair(QRegularExpression("\\[quote=([^\\]]*)\\](.*)\\[/quote\\]"), + "<figure class=\"quote\"><blockquote>\\2</blockquote></figure>"); + m_TagMap["spoiler"] = + std::make_pair(QRegularExpression("\\[spoiler\\](.*)\\[/spoiler\\]"), + "<details><summary>Spoiler: <div " + "class=\"bbc_spoiler_show\">Show</div></summary><div " + "class=\"spoiler_content\">\\1</div></details>"); + m_TagMap["code"] = std::make_pair(QRegularExpression("\\[code\\](.*)\\[/code\\]"), + "<code>\\1</code>"); + m_TagMap["heading"] = + std::make_pair(QRegularExpression("\\[heading\\](.*)\\[/heading\\]"), + "<h2><strong>\\1</strong></h2>"); + m_TagMap["line"] = std::make_pair(QRegularExpression("\\[line\\]"), "<hr>"); // lists - m_TagMap["list"] = std::make_pair(QRegularExpression("\\[list\\](.*)\\[/list\\]"), - "<ul>\\1</ul>"); - m_TagMap["list="] = std::make_pair(QRegularExpression("\\[list.*\\](.*)\\[/list\\]"), - "<ol>\\1</ol>"); - m_TagMap["ul"] = std::make_pair(QRegularExpression("\\[ul\\](.*)\\[/ul\\]"), - "<ul>\\1</ul>"); - m_TagMap["ol"] = std::make_pair(QRegularExpression("\\[ol\\](.*)\\[/ol\\]"), - "<ol>\\1</ol>"); - m_TagMap["li"] = std::make_pair(QRegularExpression("\\[li\\](.*)\\[/li\\]"), - "<li>\\1</li>"); + m_TagMap["list"] = + std::make_pair(QRegularExpression("\\[list\\](.*)\\[/list\\]"), "<ul>\\1</ul>"); + m_TagMap["list="] = std::make_pair( + QRegularExpression("\\[list.*\\](.*)\\[/list\\]"), "<ol>\\1</ol>"); + m_TagMap["ul"] = + std::make_pair(QRegularExpression("\\[ul\\](.*)\\[/ul\\]"), "<ul>\\1</ul>"); + m_TagMap["ol"] = + std::make_pair(QRegularExpression("\\[ol\\](.*)\\[/ol\\]"), "<ol>\\1</ol>"); + m_TagMap["li"] = + std::make_pair(QRegularExpression("\\[li\\](.*)\\[/li\\]"), "<li>\\1</li>"); // tables - m_TagMap["table"] = std::make_pair(QRegularExpression("\\[table\\](.*)\\[/table\\]"), - "<table>\\1</table>"); - m_TagMap["tr"] = std::make_pair(QRegularExpression("\\[tr\\](.*)\\[/tr\\]"), - "<tr>\\1</tr>"); - m_TagMap["th"] = std::make_pair(QRegularExpression("\\[th\\](.*)\\[/th\\]"), - "<th>\\1</th>"); - m_TagMap["td"] = std::make_pair(QRegularExpression("\\[td\\](.*)\\[/td\\]"), - "<td>\\1</td>"); + m_TagMap["table"] = std::make_pair( + QRegularExpression("\\[table\\](.*)\\[/table\\]"), "<table>\\1</table>"); + m_TagMap["tr"] = + std::make_pair(QRegularExpression("\\[tr\\](.*)\\[/tr\\]"), "<tr>\\1</tr>"); + m_TagMap["th"] = + std::make_pair(QRegularExpression("\\[th\\](.*)\\[/th\\]"), "<th>\\1</th>"); + m_TagMap["td"] = + std::make_pair(QRegularExpression("\\[td\\](.*)\\[/td\\]"), "<td>\\1</td>"); // web content - m_TagMap["url"] = std::make_pair(QRegularExpression("\\[url\\](.*)\\[/url\\]"), - "<a href=\"\\1\">\\1</a>"); - m_TagMap["url="] = std::make_pair(QRegularExpression("\\[url=([^\\]]*)\\](.*)\\[/url\\]"), - "<a href=\"\\1\">\\2</a>"); - m_TagMap["img"] = std::make_pair(QRegularExpression("\\[img(?:\\s*width=\\d+\\s*,?\\s*height=\\d+)?\\](.*)\\[/img\\]"), - "<img src=\"\\1\">"); - m_TagMap["img="] = std::make_pair(QRegularExpression("\\[img=([^\\]]*)\\](.*)\\[/img\\]"), - "<img src=\"\\2\" alt=\"\\1\">"); - m_TagMap["email="] = std::make_pair(QRegularExpression("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"), - "<a href=\"mailto:\\1\">\\2</a>"); - m_TagMap["youtube"] = std::make_pair(QRegularExpression("\\[youtube\\](.*)\\[/youtube\\]"), - "<a href=\"https://www.youtube.com/watch?v=\\1\">https://www.youtube.com/watch?v=\\1</a>"); - + m_TagMap["url"] = std::make_pair(QRegularExpression("\\[url\\](.*)\\[/url\\]"), + "<a href=\"\\1\">\\1</a>"); + m_TagMap["url="] = + std::make_pair(QRegularExpression("\\[url=([^\\]]*)\\](.*)\\[/url\\]"), + "<a href=\"\\1\">\\2</a>"); + m_TagMap["img"] = std::make_pair( + QRegularExpression( + "\\[img(?:\\s*width=\\d+\\s*,?\\s*height=\\d+)?\\](.*)\\[/img\\]"), + "<img src=\"\\1\">"); + m_TagMap["img="] = + std::make_pair(QRegularExpression("\\[img=([^\\]]*)\\](.*)\\[/img\\]"), + "<img src=\"\\2\" alt=\"\\1\">"); + m_TagMap["email="] = std::make_pair( + QRegularExpression("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"), + "<a href=\"mailto:\\1\">\\2</a>"); + m_TagMap["youtube"] = + std::make_pair(QRegularExpression("\\[youtube\\](.*)\\[/youtube\\]"), + "<a " + "href=\"https://www.youtube.com/watch?v=\\1\">https://" + "www.youtube.com/watch?v=\\1</a>"); // make all patterns non-greedy and case-insensitive for (TagMap::iterator iter = m_TagMap.begin(); iter != m_TagMap.end(); ++iter) { - iter->second.first.setPatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::InvertedGreedinessOption); + iter->second.first.setPatternOptions( + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::InvertedGreedinessOption); } // this tag is in fact greedy - m_TagMap["*"] = std::make_pair(QRegularExpression("\\[\\*\\](.*)"), - "<li>\\1</li>"); + m_TagMap["*"] = std::make_pair(QRegularExpression("\\[\\*\\](.*)"), "<li>\\1</li>"); m_ColorMap.insert(std::make_pair<QString, QString>("red", "FF0000")); m_ColorMap.insert(std::make_pair<QString, QString>("green", "00FF00")); @@ -227,14 +257,12 @@ private: } private: - QRegularExpression m_TagNameExp; TagMap m_TagMap; std::map<QString, QString> m_ColorMap; }; - -QString convertToHTML(const QString &inputParam) +QString convertToHTML(const QString& inputParam) { // this code goes over the input string once and replaces all bbtags // it encounters. This function is called recursively for every replaced @@ -248,7 +276,7 @@ QString convertToHTML(const QString &inputParam) input.replace("\\\"", "\"").replace("\\'", "'"); QString result; int lastBlock = 0; - int pos = 0; + int pos = 0; // iterate over the input buffer while ((pos = input.indexOf('[', lastBlock)) != -1) { @@ -256,19 +284,18 @@ QString convertToHTML(const QString &inputParam) result.append(input.mid(lastBlock, pos - lastBlock)); if ((pos < (input.size() - 1)) && (input.at(pos + 1) == '/')) { - // skip invalid end tag - int tagEnd = input.indexOf(']', pos) + 1; + // skip invalid end tag + int tagEnd = input.indexOf(']', pos) + 1; if (tagEnd == 0) { - //no closing tag found - //move the pos up one so that the opening bracket is ignored next iteration + // no closing tag found + // move the pos up one so that the opening bracket is ignored next iteration pos++; - } - else { + } else { pos = tagEnd; } } else { // convert the tag and content if necessary - int length = -1; + int length = -1; QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length); if (length != 0) { result.append(convertToHTML(replacement)); @@ -288,5 +315,4 @@ QString convertToHTML(const QString &inputParam) return result; } -} // namespace BBCode - +} // namespace BBCode |
