File indexing completed on 2025-03-09 03:57:04

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-11-19
0007  * Description : syntax highlighter for AdvancedRename utility
0008  *
0009  * SPDX-FileCopyrightText: 2009-2012 by Andi Clemens <andi dot clemens at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "highlighter.h"
0016 
0017 // Qt includes
0018 
0019 #include <QTextDocument>
0020 
0021 // Local includes
0022 
0023 #include "parser.h"
0024 
0025 namespace Digikam
0026 {
0027 
0028 Highlighter::Highlighter(QTextDocument* const document, Parser* const _parser)
0029     : QSyntaxHighlighter(document),
0030       parser            (_parser)
0031 
0032 {
0033     setupHighlightingGrammar();
0034 }
0035 
0036 Highlighter::~Highlighter()
0037 {
0038 }
0039 
0040 void Highlighter::highlightBlock(const QString& text)
0041 {
0042     Q_FOREACH (const HighlightingRule& rule, highlightingRules)
0043     {
0044         QRegularExpression      expression(rule.pattern);
0045         QRegularExpressionMatch match;
0046         int index = text.indexOf(expression, 0, &match);
0047 
0048         while (index >= 0)
0049         {
0050             int length = match.capturedLength();
0051             setFormat(index, length, rule.format);
0052 
0053             switch (rule.type)
0054             {
0055                 case OptionPattern:
0056                 case ModifierPattern:
0057                 {
0058                     // highlight parameters in options and modifiers
0059 
0060                     if ((expression.captureCount() > 0) && !match.captured(1).isEmpty())
0061                     {
0062                         QString fullmatched  = match.captured(0);
0063                         QString parameters   = match.captured(1);
0064 
0065                         if (parameters.startsWith(QLatin1Char(':')))
0066                         {
0067                             parameters.remove(0, 1);
0068 
0069                             if (!parameters.isEmpty())
0070                             {
0071                                 int pindex = fullmatched.indexOf(parameters);
0072 
0073                                 while (pindex >= 0)
0074                                 {
0075                                     int plength = parameters.length();
0076                                     setFormat(index + pindex, plength, parameterFormat);
0077                                     pindex      = fullmatched.indexOf(parameters, pindex + plength);
0078                                 }
0079                             }
0080                         }
0081                     }
0082 
0083                     break;
0084                 }
0085 
0086                 default:
0087                 {
0088                     break;
0089                 }
0090             }
0091 
0092             index = text.indexOf(expression, index+length, &match);
0093         }
0094     }
0095 
0096     // mark invalid modifiers in the parse string
0097 
0098     ParseSettings settings;
0099     settings.parseString = text;
0100     ParseResults invalid = parser->invalidModifiers(settings);
0101 
0102     Q_FOREACH (const ParseResults::ResultsKey& key, invalid.keys())
0103     {
0104         setFormat(key.first, key.second, errorFormat);
0105     }
0106 
0107     // highlight quoted text in options and modifiers
0108 
0109     {
0110         QRegularExpression      expression(quotationRule.pattern);
0111         QRegularExpressionMatch match;
0112         int index = text.indexOf(expression, 0, &match);
0113 
0114         while (index >= 0)
0115         {
0116             QString fullmatched = match.captured(0);
0117             int qlength         = match.capturedLength();
0118             setFormat(index, qlength, quotationFormat);
0119             index = text.indexOf(expression, index + qlength, &match);
0120         }
0121     }
0122 }
0123 
0124 void Highlighter::setupHighlightingGrammar()
0125 {
0126     if (!parser)
0127     {
0128         return;
0129     }
0130 
0131     HighlightingRule rule;
0132 
0133     // --------------------------------------------------------
0134 
0135     optionFormat.setForeground(Qt::red);
0136 
0137     Q_FOREACH (Rule* const option, parser->options())
0138     {
0139         QRegularExpression r    = option->regExp();
0140         rule.type               = OptionPattern;
0141         rule.pattern            = r;
0142         rule.format             = optionFormat;
0143         highlightingRules.append(rule);
0144     }
0145 
0146     // --------------------------------------------------------
0147 
0148     modifierFormat.setForeground(Qt::darkGreen);
0149 
0150     Q_FOREACH (Rule* const modifier, parser->modifiers())
0151     {
0152         QRegularExpression r    = modifier->regExp();
0153         rule.type               = ModifierPattern;
0154         rule.pattern            = r;
0155         rule.format             = modifierFormat;
0156         highlightingRules.append(rule);
0157     }
0158 
0159     // --------------------------------------------------------
0160 
0161     quotationFormat.setForeground(QColor(0x50, 0x50, 0xff)); // light blue
0162     quotationFormat.setFontItalic(true);
0163     quotationRule.pattern = QRegularExpression(QLatin1String("\".*\""));
0164     quotationRule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
0165     quotationRule.format  = quotationFormat;
0166     quotationRule.type    = QuotedTextPattern;
0167 
0168     // --------------------------------------------------------
0169 
0170     parameterFormat.setForeground(Qt::darkYellow);
0171     parameterFormat.setFontItalic(true);
0172 
0173     // --------------------------------------------------------
0174 
0175     errorFormat.setForeground(Qt::white);
0176     errorFormat.setBackground(Qt::red);
0177 }
0178 
0179 } // namespace Digikam
0180 
0181 #include "moc_highlighter.cpp"