File indexing completed on 2025-01-19 04:46:50

0001 /*
0002    SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "highlighter.h"
0008 
0009 #include <KSyntaxHighlighting/Format>
0010 #include <KSyntaxHighlighting/State>
0011 #include <KSyntaxHighlighting/Theme>
0012 
0013 #include <QTextStream>
0014 
0015 Highlighter::Highlighter(QTextStream *stream)
0016     : mStream(stream)
0017 {
0018 }
0019 
0020 Highlighter::~Highlighter() = default;
0021 
0022 void Highlighter::highlight(const QString &str)
0023 {
0024     *mStream << QStringLiteral("<pre class=\"highlightattachment\">");
0025 
0026     KSyntaxHighlighting::State state;
0027 
0028     int lineStart = 0;
0029     int lineEnd = str.indexOf(QLatin1Char('\n'));
0030 
0031     for (; lineEnd != -1; lineStart = lineEnd + 1, lineEnd = str.indexOf(QLatin1Char('\n'), lineStart)) {
0032         mCurrentLine = str.mid(lineStart, lineEnd - lineStart);
0033         state = highlightLine(mCurrentLine, state);
0034         *mStream << QLatin1Char('\n');
0035     }
0036     if (lineStart < str.size()) { // remaining content if str isn't ending with a newline
0037         mCurrentLine = str.mid(lineStart);
0038         state = highlightLine(mCurrentLine, state);
0039         *mStream << QLatin1Char('\n');
0040     }
0041     *mStream << QLatin1StringView("</pre>\n");
0042 }
0043 
0044 void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
0045 {
0046     if (!format.isDefaultTextStyle(theme())) {
0047         *mStream << QStringLiteral("<span style=\"");
0048         if (format.hasTextColor(theme())) {
0049             *mStream << QStringLiteral("color:") << format.textColor(theme()).name() << QLatin1Char(';');
0050         }
0051         if (format.hasBackgroundColor(theme())) {
0052             *mStream << QStringLiteral("background-color:") << format.backgroundColor(theme()).name() << QLatin1Char(';');
0053         }
0054         if (format.isBold(theme())) {
0055             *mStream << QStringLiteral("font-weight:bold;");
0056         }
0057         if (format.isItalic(theme())) {
0058             *mStream << QStringLiteral("font-style:italic;");
0059         }
0060         if (format.isUnderline(theme())) {
0061             *mStream << QStringLiteral("text-decoration:underline;");
0062         }
0063         if (format.isStrikeThrough(theme())) {
0064             *mStream << QStringLiteral("text-decoration:line-through;");
0065         }
0066         *mStream << QStringLiteral("\">");
0067     }
0068 
0069     *mStream << mCurrentLine.mid(offset, length).toHtmlEscaped();
0070 
0071     if (!format.isDefaultTextStyle(theme())) {
0072         *mStream << QStringLiteral("</span>");
0073     }
0074 }