File indexing completed on 2024-10-27 04:39:16

0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 // SPDX-FileCopyrightText: 2023 Louis Schul <schul9louis@gmail.com>
0003 
0004 #include "highlightHelper.h"
0005 #include "../cliHelper.h"
0006 #include "kleverconfig.h"
0007 // #include <QDebug>
0008 
0009 HighlightHelper::HighlightHelper(QObject *parent)
0010     : QObject(parent)
0011 {
0012     setAvailableHighlighters();
0013 }
0014 
0015 QString HighlightHelper::getHighlightedString(const QString &inputStr, const QString &lang)
0016 {
0017     const QString highlighter = KleverConfig::codeSynthaxHighlighter();
0018     const QString style = KleverConfig::codeSynthaxHighlighterStyle();
0019 
0020     if (inputStr.isEmpty() || lang.isEmpty() || !m_availableHighlighters.contains(highlighter)) {
0021         return inputStr;
0022     }
0023 
0024     QString cmd = highlighter + m_highlightersCommands[highlighter].last();
0025     static const QRegularExpression nord = QRegularExpression(QStringLiteral("[Nn]ord"));
0026     cmd.replace(QStringLiteral("%1"), lang);
0027     if (m_availableHighlighters[highlighter].contains(style)) {
0028         cmd.replace(nord, style);
0029     }
0030 
0031     const QString echo = QStringLiteral("echo \"") + inputStr + QStringLiteral("\" | ");
0032 
0033     cmd = echo + cmd;
0034 
0035     QString output = CLIHelper::execCommand(cmd);
0036 
0037     if (output.isEmpty()) {
0038         return inputStr;
0039     }
0040 
0041     const bool isChroma = highlighter == m_chromaName;
0042     const bool isPygmentizeOrKSyntaxHighlither = highlighter == m_pygmentizeName || highlighter == m_kSyntaxName || highlighter == m_kateSyntaxName;
0043 
0044     int startIndex = -1;
0045     int endIndex = -1;
0046     if (isChroma) {
0047         static const auto codeBlockStart = QStringLiteral("<code>");
0048         startIndex = output.indexOf(codeBlockStart) + codeBlockStart.length();
0049         endIndex = output.lastIndexOf(QStringLiteral("</code>"));
0050     } else if (isPygmentizeOrKSyntaxHighlither) {
0051         startIndex = output.indexOf(QStringLiteral("<span"));
0052         endIndex = output.lastIndexOf(QStringLiteral("\n</pre>"));
0053     }
0054 
0055     const bool correctIndexes = startIndex < endIndex && -1 < startIndex && -1 < endIndex;
0056 
0057     output = correctIndexes ? output.mid(startIndex, endIndex - startIndex) : QString();
0058 
0059     return output.isEmpty() ? inputStr : output;
0060 }
0061 
0062 QStringList HighlightHelper::getHighlighters() const
0063 {
0064     return m_availableHighlighters.keys();
0065 }
0066 
0067 QStringList HighlightHelper::getHighlighterStyle(const QString &highlighter) const
0068 {
0069     return m_availableHighlighters.contains(highlighter) ? m_availableHighlighters[highlighter] : QStringList();
0070 }
0071 
0072 QStringList HighlightHelper::getHighlighterStyleFromCmd(const QString &highlighter) const
0073 {
0074     QStringList styles;
0075 
0076     const QString cmd = highlighter + m_highlightersCommands[highlighter].constFirst();
0077     const QString output = CLIHelper::execCommand(cmd);
0078 
0079     if (output.isEmpty()) {
0080         return styles;
0081     }
0082 
0083     if (highlighter == m_pygmentizeName) {
0084         auto it = m_pygmentizeRegex.globalMatch(output);
0085 
0086         while (it.hasNext()) {
0087             const QRegularExpressionMatch match = it.next();
0088             styles.append(match.captured(2));
0089         }
0090     } else if (highlighter == m_chromaName) {
0091         static const auto styleStart = QStringLiteral("\nstyles: ");
0092         const int startIndex = output.lastIndexOf(styleStart) + styleStart.length();
0093         const int endIndex = output.lastIndexOf(QStringLiteral("\nformatters: "));
0094 
0095         styles = output.mid(startIndex, endIndex - startIndex).split(QStringLiteral(" "));
0096     } else if (highlighter == m_kSyntaxName || highlighter == m_kateSyntaxName) {
0097         styles = output.split(QStringLiteral("\n"));
0098         styles.takeLast(); // there's a blank line at the end
0099     }
0100 
0101     styles.sort();
0102     return styles;
0103 }
0104 
0105 void HighlightHelper::setAvailableHighlighters()
0106 {
0107     for (auto it = m_highlightersCommands.cbegin(); it != m_highlightersCommands.cend(); it++) {
0108         if (CLIHelper::commandExists(it.key())) {
0109             m_availableHighlighters[it.key()] = getHighlighterStyleFromCmd(it.key());
0110         }
0111     }
0112 }