From 86bb01ba9eac879d3685c439ac9da0028bc4bc80 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Tue, 17 May 2022 11:37:19 +0200 Subject: Convert everything to CRLF. --- src/bbcode.cpp | 584 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 292 insertions(+), 292 deletions(-) (limited to 'src/bbcode.cpp') diff --git a/src/bbcode.cpp b/src/bbcode.cpp index 36b60a66..e143909f 100644 --- a/src/bbcode.cpp +++ b/src/bbcode.cpp @@ -1,292 +1,292 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Mod Organizer. If not, see . -*/ - -#include "bbcode.h" -#include -#include -#include - -namespace BBCode { - -namespace log = MOBase::log; - -class BBCodeMap { - - typedef std::map > TagMap; - -public: - - static BBCodeMap &instance() { - static BBCodeMap s_Instance; - return s_Instance; - } - - QString convertTag(QString input, int &length) - { - // extract the tag name - 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()) { - // recognized tag - if (tagName.endsWith('=')) { - tagName.chop(1); - } - - int closeTagPos = 0; - int nextTagPos = 0; - int nextTagSearchIndex = input.indexOf("]"); - int closeTagLength = 0; - if (tagName == "*") { - // ends at the next bullet point - closeTagPos = input.indexOf(QRegularExpression("(\\[\\*\\]|)", 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); - QString closeTag = QString("[/%1]").arg(tagName); - 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); - nextTagSearchIndex = input.indexOf("]", nextTagPos); - nextTagPos = nextTag.match(input, nextTagSearchIndex).capturedStart(0); - } - if (closeTagPos == -1) { - // workaround to improve compatibility: add fake closing tag - input.append(closeTag); - closeTagPos = input.size() - closeTag.size(); - } - closeTagLength = closeTag.size(); - } - - if (closeTagPos > -1) { - length = closeTagPos + closeTagLength; - QString temp = input.mid(0, length); - 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 content = match.captured(2); - if (color.at(0) == '#') { - return temp.replace(tagIter->second.first, QString("%2").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("%2").arg(color, content)); - } - } else { - log::warn("don't know how to deal with tag {}", tagName); - } - } else { - if (tagName == "*") { - temp.remove(QRegularExpression("(\\[/\\*\\])?(
)?$")); - } - return temp.replace(tagIter->second.first, tagIter->second.second); - } - } else { - // expression doesn't match. either the input string is invalid - // or the expression is - log::warn("{} doesn't match the expression for {}", temp, tagName); - length = 0; - return QString(); - } - } - } - - // not a recognized tag or tag invalid - length = 0; - return QString(); - } - -private: - BBCodeMap() - : m_TagNameExp("[a-zA-Z*]*=?") - { - m_TagMap["b"] = std::make_pair(QRegularExpression("\\[b\\](.*)\\[/b\\]"), - "\\1"); - m_TagMap["i"] = std::make_pair(QRegularExpression("\\[i\\](.*)\\[/i\\]"), - "\\1"); - m_TagMap["u"] = std::make_pair(QRegularExpression("\\[u\\](.*)\\[/u\\]"), - "\\1"); - m_TagMap["s"] = std::make_pair(QRegularExpression("\\[s\\](.*)\\[/s\\]"), - "\\1"); - m_TagMap["sub"] = std::make_pair(QRegularExpression("\\[sub\\](.*)\\[/sub\\]"), - "\\1"); - m_TagMap["sup"] = std::make_pair(QRegularExpression("\\[sup\\](.*)\\[/sup\\]"), - "\\1"); - m_TagMap["size="] = std::make_pair(QRegularExpression("\\[size=([^\\]]*)\\](.*)\\[/size\\]"), - "\\2"); - m_TagMap["color="] = std::make_pair(QRegularExpression("\\[color=([^\\]]*)\\](.*)\\[/color\\]"), - ""); - m_TagMap["font="] = std::make_pair(QRegularExpression("\\[font=([^\\]]*)\\](.*)\\[/font\\]"), - "\\2"); - m_TagMap["center"] = std::make_pair(QRegularExpression("\\[center\\](.*)\\[/center\\]"), - "
\\1
"); - m_TagMap["right"] = std::make_pair(QRegularExpression("\\[right\\](.*)\\[/right\\]"), - "
\\1
"); - m_TagMap["quote"] = std::make_pair(QRegularExpression("\\[quote\\](.*)\\[/quote\\]"), - "
\\1
"); - m_TagMap["quote="] = std::make_pair(QRegularExpression("\\[quote=([^\\]]*)\\](.*)\\[/quote\\]"), - "
\\2
"); - m_TagMap["spoiler"] = std::make_pair(QRegularExpression("\\[spoiler\\](.*)\\[/spoiler\\]"), - "
Spoiler:
Show
\\1
"); - m_TagMap["code"] = std::make_pair(QRegularExpression("\\[code\\](.*)\\[/code\\]"), - "\\1"); - m_TagMap["heading"]= std::make_pair(QRegularExpression("\\[heading\\](.*)\\[/heading\\]"), - "

\\1

"); - m_TagMap["line"] = std::make_pair(QRegularExpression("\\[line\\]"), - "
"); - - // lists - m_TagMap["list"] = std::make_pair(QRegularExpression("\\[list\\](.*)\\[/list\\]"), - "
    \\1
"); - m_TagMap["list="] = std::make_pair(QRegularExpression("\\[list.*\\](.*)\\[/list\\]"), - "
    \\1
"); - m_TagMap["ul"] = std::make_pair(QRegularExpression("\\[ul\\](.*)\\[/ul\\]"), - "
    \\1
"); - m_TagMap["ol"] = std::make_pair(QRegularExpression("\\[ol\\](.*)\\[/ol\\]"), - "
    \\1
"); - m_TagMap["li"] = std::make_pair(QRegularExpression("\\[li\\](.*)\\[/li\\]"), - "
  • \\1
  • "); - - // tables - m_TagMap["table"] = std::make_pair(QRegularExpression("\\[table\\](.*)\\[/table\\]"), - "\\1
    "); - m_TagMap["tr"] = std::make_pair(QRegularExpression("\\[tr\\](.*)\\[/tr\\]"), - "\\1"); - m_TagMap["th"] = std::make_pair(QRegularExpression("\\[th\\](.*)\\[/th\\]"), - "\\1"); - m_TagMap["td"] = std::make_pair(QRegularExpression("\\[td\\](.*)\\[/td\\]"), - "\\1"); - - // web content - m_TagMap["url"] = std::make_pair(QRegularExpression("\\[url\\](.*)\\[/url\\]"), - "\\1"); - m_TagMap["url="] = std::make_pair(QRegularExpression("\\[url=([^\\]]*)\\](.*)\\[/url\\]"), - "\\2"); - m_TagMap["img"] = std::make_pair(QRegularExpression("\\[img(?:\\s*width=\\d+\\s*,?\\s*height=\\d+)?\\](.*)\\[/img\\]"), - ""); - m_TagMap["img="] = std::make_pair(QRegularExpression("\\[img=([^\\]]*)\\](.*)\\[/img\\]"), - "\"\\1\""); - m_TagMap["email="] = std::make_pair(QRegularExpression("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"), - "\\2"); - m_TagMap["youtube"] = std::make_pair(QRegularExpression("\\[youtube\\](.*)\\[/youtube\\]"), - "https://www.youtube.com/watch?v=\\1"); - - - // 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); - } - - // this tag is in fact greedy - m_TagMap["*"] = std::make_pair(QRegularExpression("\\[\\*\\](.*)"), - "
  • \\1
  • "); - - m_ColorMap.insert(std::make_pair("red", "FF0000")); - m_ColorMap.insert(std::make_pair("green", "00FF00")); - m_ColorMap.insert(std::make_pair("blue", "0000FF")); - m_ColorMap.insert(std::make_pair("black", "000000")); - m_ColorMap.insert(std::make_pair("gray", "7F7F7F")); - m_ColorMap.insert(std::make_pair("white", "FFFFFF")); - m_ColorMap.insert(std::make_pair("yellow", "FFFF00")); - m_ColorMap.insert(std::make_pair("cyan", "00FFFF")); - m_ColorMap.insert(std::make_pair("magenta", "FF00FF")); - m_ColorMap.insert(std::make_pair("brown", "A52A2A")); - m_ColorMap.insert(std::make_pair("orange", "FFA500")); - m_ColorMap.insert(std::make_pair("gold", "FFD700")); - m_ColorMap.insert(std::make_pair("deepskyblue", "00BFFF")); - m_ColorMap.insert(std::make_pair("salmon", "FA8072")); - m_ColorMap.insert(std::make_pair("dodgerblue", "1E90FF")); - m_ColorMap.insert(std::make_pair("greenyellow", "ADFF2F")); - m_ColorMap.insert(std::make_pair("peru", "CD853F")); - } - -private: - - QRegularExpression m_TagNameExp; - TagMap m_TagMap; - std::map m_ColorMap; -}; - - -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 - // string to convert nested tags. - // - // This could be implemented simpler by applying a set of regular expressions - // for each recognized bb-tag one after the other but that would probably be - // very inefficient (O(n^2)). - - QString input = inputParam.mid(0).replace("\r\n", "
    "); - input.replace("\\\"", "\"").replace("\\'", "'"); - QString result; - int lastBlock = 0; - int pos = 0; - - // iterate over the input buffer - while ((pos = input.indexOf('[', lastBlock)) != -1) { - // append everything between the previous tag-block and the current one - 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; - if (tagEnd == 0) { - //no closing tag found - //move the pos up one so that the opening bracket is ignored next iteration - pos++; - } - else { - pos = tagEnd; - } - } else { - // convert the tag and content if necessary - int length = -1; - QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length); - if (length != 0) { - result.append(convertToHTML(replacement)); - // length contains the number of characters in the original tag - pos += length; - } else { - // nothing replaced - result.append('['); - ++pos; - } - } - lastBlock = pos; - } - - // append the remainder (everything after the last tag) - result.append(input.mid(lastBlock)); - return result; -} - -} // namespace BBCode - +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#include "bbcode.h" +#include +#include +#include + +namespace BBCode { + +namespace log = MOBase::log; + +class BBCodeMap { + + typedef std::map > TagMap; + +public: + + static BBCodeMap &instance() { + static BBCodeMap s_Instance; + return s_Instance; + } + + QString convertTag(QString input, int &length) + { + // extract the tag name + 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()) { + // recognized tag + if (tagName.endsWith('=')) { + tagName.chop(1); + } + + int closeTagPos = 0; + int nextTagPos = 0; + int nextTagSearchIndex = input.indexOf("]"); + int closeTagLength = 0; + if (tagName == "*") { + // ends at the next bullet point + closeTagPos = input.indexOf(QRegularExpression("(\\[\\*\\]|)", 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); + QString closeTag = QString("[/%1]").arg(tagName); + 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); + nextTagSearchIndex = input.indexOf("]", nextTagPos); + nextTagPos = nextTag.match(input, nextTagSearchIndex).capturedStart(0); + } + if (closeTagPos == -1) { + // workaround to improve compatibility: add fake closing tag + input.append(closeTag); + closeTagPos = input.size() - closeTag.size(); + } + closeTagLength = closeTag.size(); + } + + if (closeTagPos > -1) { + length = closeTagPos + closeTagLength; + QString temp = input.mid(0, length); + 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 content = match.captured(2); + if (color.at(0) == '#') { + return temp.replace(tagIter->second.first, QString("%2").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("%2").arg(color, content)); + } + } else { + log::warn("don't know how to deal with tag {}", tagName); + } + } else { + if (tagName == "*") { + temp.remove(QRegularExpression("(\\[/\\*\\])?(
    )?$")); + } + return temp.replace(tagIter->second.first, tagIter->second.second); + } + } else { + // expression doesn't match. either the input string is invalid + // or the expression is + log::warn("{} doesn't match the expression for {}", temp, tagName); + length = 0; + return QString(); + } + } + } + + // not a recognized tag or tag invalid + length = 0; + return QString(); + } + +private: + BBCodeMap() + : m_TagNameExp("[a-zA-Z*]*=?") + { + m_TagMap["b"] = std::make_pair(QRegularExpression("\\[b\\](.*)\\[/b\\]"), + "\\1"); + m_TagMap["i"] = std::make_pair(QRegularExpression("\\[i\\](.*)\\[/i\\]"), + "\\1"); + m_TagMap["u"] = std::make_pair(QRegularExpression("\\[u\\](.*)\\[/u\\]"), + "\\1"); + m_TagMap["s"] = std::make_pair(QRegularExpression("\\[s\\](.*)\\[/s\\]"), + "\\1"); + m_TagMap["sub"] = std::make_pair(QRegularExpression("\\[sub\\](.*)\\[/sub\\]"), + "\\1"); + m_TagMap["sup"] = std::make_pair(QRegularExpression("\\[sup\\](.*)\\[/sup\\]"), + "\\1"); + m_TagMap["size="] = std::make_pair(QRegularExpression("\\[size=([^\\]]*)\\](.*)\\[/size\\]"), + "\\2"); + m_TagMap["color="] = std::make_pair(QRegularExpression("\\[color=([^\\]]*)\\](.*)\\[/color\\]"), + ""); + m_TagMap["font="] = std::make_pair(QRegularExpression("\\[font=([^\\]]*)\\](.*)\\[/font\\]"), + "\\2"); + m_TagMap["center"] = std::make_pair(QRegularExpression("\\[center\\](.*)\\[/center\\]"), + "
    \\1
    "); + m_TagMap["right"] = std::make_pair(QRegularExpression("\\[right\\](.*)\\[/right\\]"), + "
    \\1
    "); + m_TagMap["quote"] = std::make_pair(QRegularExpression("\\[quote\\](.*)\\[/quote\\]"), + "
    \\1
    "); + m_TagMap["quote="] = std::make_pair(QRegularExpression("\\[quote=([^\\]]*)\\](.*)\\[/quote\\]"), + "
    \\2
    "); + m_TagMap["spoiler"] = std::make_pair(QRegularExpression("\\[spoiler\\](.*)\\[/spoiler\\]"), + "
    Spoiler:
    Show
    \\1
    "); + m_TagMap["code"] = std::make_pair(QRegularExpression("\\[code\\](.*)\\[/code\\]"), + "\\1"); + m_TagMap["heading"]= std::make_pair(QRegularExpression("\\[heading\\](.*)\\[/heading\\]"), + "

    \\1

    "); + m_TagMap["line"] = std::make_pair(QRegularExpression("\\[line\\]"), + "
    "); + + // lists + m_TagMap["list"] = std::make_pair(QRegularExpression("\\[list\\](.*)\\[/list\\]"), + "
      \\1
    "); + m_TagMap["list="] = std::make_pair(QRegularExpression("\\[list.*\\](.*)\\[/list\\]"), + "
      \\1
    "); + m_TagMap["ul"] = std::make_pair(QRegularExpression("\\[ul\\](.*)\\[/ul\\]"), + "
      \\1
    "); + m_TagMap["ol"] = std::make_pair(QRegularExpression("\\[ol\\](.*)\\[/ol\\]"), + "
      \\1
    "); + m_TagMap["li"] = std::make_pair(QRegularExpression("\\[li\\](.*)\\[/li\\]"), + "
  • \\1
  • "); + + // tables + m_TagMap["table"] = std::make_pair(QRegularExpression("\\[table\\](.*)\\[/table\\]"), + "\\1
    "); + m_TagMap["tr"] = std::make_pair(QRegularExpression("\\[tr\\](.*)\\[/tr\\]"), + "\\1"); + m_TagMap["th"] = std::make_pair(QRegularExpression("\\[th\\](.*)\\[/th\\]"), + "\\1"); + m_TagMap["td"] = std::make_pair(QRegularExpression("\\[td\\](.*)\\[/td\\]"), + "\\1"); + + // web content + m_TagMap["url"] = std::make_pair(QRegularExpression("\\[url\\](.*)\\[/url\\]"), + "\\1"); + m_TagMap["url="] = std::make_pair(QRegularExpression("\\[url=([^\\]]*)\\](.*)\\[/url\\]"), + "\\2"); + m_TagMap["img"] = std::make_pair(QRegularExpression("\\[img(?:\\s*width=\\d+\\s*,?\\s*height=\\d+)?\\](.*)\\[/img\\]"), + ""); + m_TagMap["img="] = std::make_pair(QRegularExpression("\\[img=([^\\]]*)\\](.*)\\[/img\\]"), + "\"\\1\""); + m_TagMap["email="] = std::make_pair(QRegularExpression("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"), + "\\2"); + m_TagMap["youtube"] = std::make_pair(QRegularExpression("\\[youtube\\](.*)\\[/youtube\\]"), + "https://www.youtube.com/watch?v=\\1"); + + + // 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); + } + + // this tag is in fact greedy + m_TagMap["*"] = std::make_pair(QRegularExpression("\\[\\*\\](.*)"), + "
  • \\1
  • "); + + m_ColorMap.insert(std::make_pair("red", "FF0000")); + m_ColorMap.insert(std::make_pair("green", "00FF00")); + m_ColorMap.insert(std::make_pair("blue", "0000FF")); + m_ColorMap.insert(std::make_pair("black", "000000")); + m_ColorMap.insert(std::make_pair("gray", "7F7F7F")); + m_ColorMap.insert(std::make_pair("white", "FFFFFF")); + m_ColorMap.insert(std::make_pair("yellow", "FFFF00")); + m_ColorMap.insert(std::make_pair("cyan", "00FFFF")); + m_ColorMap.insert(std::make_pair("magenta", "FF00FF")); + m_ColorMap.insert(std::make_pair("brown", "A52A2A")); + m_ColorMap.insert(std::make_pair("orange", "FFA500")); + m_ColorMap.insert(std::make_pair("gold", "FFD700")); + m_ColorMap.insert(std::make_pair("deepskyblue", "00BFFF")); + m_ColorMap.insert(std::make_pair("salmon", "FA8072")); + m_ColorMap.insert(std::make_pair("dodgerblue", "1E90FF")); + m_ColorMap.insert(std::make_pair("greenyellow", "ADFF2F")); + m_ColorMap.insert(std::make_pair("peru", "CD853F")); + } + +private: + + QRegularExpression m_TagNameExp; + TagMap m_TagMap; + std::map m_ColorMap; +}; + + +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 + // string to convert nested tags. + // + // This could be implemented simpler by applying a set of regular expressions + // for each recognized bb-tag one after the other but that would probably be + // very inefficient (O(n^2)). + + QString input = inputParam.mid(0).replace("\r\n", "
    "); + input.replace("\\\"", "\"").replace("\\'", "'"); + QString result; + int lastBlock = 0; + int pos = 0; + + // iterate over the input buffer + while ((pos = input.indexOf('[', lastBlock)) != -1) { + // append everything between the previous tag-block and the current one + 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; + if (tagEnd == 0) { + //no closing tag found + //move the pos up one so that the opening bracket is ignored next iteration + pos++; + } + else { + pos = tagEnd; + } + } else { + // convert the tag and content if necessary + int length = -1; + QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length); + if (length != 0) { + result.append(convertToHTML(replacement)); + // length contains the number of characters in the original tag + pos += length; + } else { + // nothing replaced + result.append('['); + ++pos; + } + } + lastBlock = pos; + } + + // append the remainder (everything after the last tag) + result.append(input.mid(lastBlock)); + return result; +} + +} // namespace BBCode + -- cgit v1.3.1