diff --git a/plugins/clazy/utils.cpp b/plugins/clazy/utils.cpp index 8fb1f26f13..1785038ffb 100644 --- a/plugins/clazy/utils.cpp +++ b/plugins/clazy/utils.cpp @@ -1,199 +1,201 @@ /* This file is part of KDevelop Copyright 2018 Anton Anikin This program 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 2 of the License, or (at your option) any later version. This program 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 this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "utils.h" +// KDevPlatform #include #include #include - +// KF #include - +// Qt #include #include +#include namespace Clazy { QString prettyPathName(const QUrl& path) { return KDevelop::ICore::self()->projectController()->prettyFileName(path, KDevelop::IProjectController::FormatPlain); } // Very simple Markdown parser/converter. Does not provide full Markdown language support and // was tested only with Clazy documentation. class MarkdownConverter { public: MarkdownConverter() { tagStart.resize(STATE_COUNT); tagEnd.resize(STATE_COUNT); tagStart[EMPTY].clear(); tagEnd [EMPTY].clear(); tagStart[HEADING] = QStringLiteral(""); tagEnd [HEADING] = QStringLiteral(""); tagStart[PARAGRAPH] = QStringLiteral("

"); tagEnd [PARAGRAPH] = QStringLiteral("

"); tagStart[PREFORMATTED] = QStringLiteral("
");
         tagEnd  [PREFORMATTED] = QStringLiteral("
"); tagStart[LIST] = QStringLiteral("
  • "); tagEnd [LIST] = QStringLiteral("
"); } ~MarkdownConverter() = default; QString toHtml(const QString& markdown) { const QRegularExpression hRE(QStringLiteral("(#+) (.+)")); QRegularExpressionMatch match; state = EMPTY; html.clear(); html += QStringLiteral(""); auto lines = markdown.split(QLatin1Char('\n')); for (auto line : lines) { if (line.isEmpty()) { setState(EMPTY); continue; } if (line.startsWith(QLatin1Char('#'))) { auto match = hRE.match(line); if (match.hasMatch()) { setState(HEADING); html += match.captured(2); setState(EMPTY); if (match.capturedRef(1).size() == 1) { html += QStringLiteral("
"); } } continue; } if (line.startsWith(QLatin1String("```"))) { setState((state == PREFORMATTED) ? EMPTY : PREFORMATTED); continue; } if (line.startsWith(QLatin1String(" "))) { if (state == EMPTY) { setState(PREFORMATTED); } } else if ( line.startsWith(QLatin1String("- ")) || line.startsWith(QLatin1String("* "))) { // force close and reopen list - this fixes cases when we don't have // separator line between items setState(EMPTY); setState(LIST); line.remove(0, 2); } if (state == EMPTY) { setState(PARAGRAPH); } processLine(line); } setState(EMPTY); html += QStringLiteral(""); return html.join(QLatin1Char('\n')); } private: enum STATE { EMPTY, HEADING, PARAGRAPH, PREFORMATTED, LIST, STATE_COUNT }; void setState(int newState) { if (state == newState) { return; } if (state != EMPTY) { html += tagEnd[state]; } if (newState != EMPTY) { html += tagStart[newState]; } state = newState; } void processLine(QString& line) { static const QRegularExpression ttRE(QStringLiteral("`([^`]+)`")); static const QRegularExpression bdRE(QStringLiteral("\\*\\*([^\\*]+)\\*\\*")); static const QRegularExpression itRE(QStringLiteral("[^\\*]\\*([^\\*]+)\\*[^\\*]")); static auto applyRE = [](const QRegularExpression& re, QString& line, const QString& tag) { auto i = re.globalMatch(line); while (i.hasNext()) { auto match = i.next(); line.replace(match.captured(0), QStringLiteral("<%1>%2").arg(tag, match.captured(1))); } }; if (state != PREFORMATTED) { line.replace(QLatin1Char('&'), QLatin1String("&")); line.replace(QLatin1Char('<'), QLatin1String("<")); line.replace(QLatin1Char('>'), QLatin1String(">")); line.replace(QLatin1Char('\"'), QLatin1String(""")); line.replace(QLatin1Char('\''), QLatin1String("'")); applyRE(ttRE, line, QStringLiteral("tt")); applyRE(bdRE, line, QStringLiteral("b")); applyRE(itRE, line, QStringLiteral("i")); } html += line; } private: int state; QVector tagStart; QVector tagEnd; QStringList html; }; QString markdown2html(const QByteArray& markdown) { MarkdownConverter converter; return converter.toHtml(QString::fromUtf8(markdown)); } }