8#include "htmlhighlighter.h"
9#include "abstracthighlighter_p.h"
10#include "definition.h"
11#include "definition_p.h"
13#include "ksyntaxhighlighting_logging.h"
24class KSyntaxHighlighting::HtmlHighlighterPrivate :
public AbstractHighlighterPrivate
27 std::unique_ptr<QTextStream> out;
28 std::unique_ptr<QFile> file;
30 std::vector<QString> htmlStyles;
34HtmlHighlighter::HtmlHighlighter()
39HtmlHighlighter::~HtmlHighlighter()
49void HtmlHighlighter::setOutputFile(
const QString &fileName)
52 d->file.reset(
new QFile(fileName));
54 qCWarning(Log) <<
"Failed to open output file" << fileName <<
":" << d->file->errorString();
57 d->out.reset(
new QTextStream(d->file.get()));
61void HtmlHighlighter::setOutputFile(FILE *fileHandle)
68void HtmlHighlighter::highlightFile(
const QString &fileName,
const QString &title)
72 qCWarning(Log) <<
"Failed to open input file" << fileName <<
":" << f.errorString();
77 QFileInfo fi(fileName);
78 highlightData(&f, fi.fileName());
80 highlightData(&f, title);
95 static const char16_t *digits = u
"0123456789abcdef";
98 hexcode[1] = digits[qRed(argb) >> 4];
99 hexcode[2] = digits[qRed(argb) & 0xf];
100 hexcode[3] = digits[qGreen(argb) >> 4];
101 hexcode[4] = digits[qGreen(argb) & 0xf];
102 hexcode[5] = digits[qBlue(argb) >> 4];
103 hexcode[6] = digits[qBlue(argb) & 0xf];
104 if (qAlpha(argb) == 0xff) {
107 hexcode[7] = digits[qAlpha(argb) >> 4];
108 hexcode[8] = digits[qAlpha(argb) & 0xf];
113 QStringView sv()
const
115 return QStringView(hexcode, len);
124void HtmlHighlighter::highlightData(QIODevice *dev,
const QString &title)
126 Q_D(HtmlHighlighter);
129 qCWarning(Log) <<
"No output stream defined!";
135 htmlTitle = QStringLiteral(
"KSyntaxHighlighter");
140 const auto &
theme = d->m_theme;
144 auto definitions =
definition.includedDefinitions();
147 const auto mainTextColor = [&] {
148 if (useSelectedText) {
156 const auto mainBgColor =
theme.editorColor(d->bgRole);
159 for (
const auto &
definition : std::as_const(definitions)) {
160 for (
const auto &format : std::as_const(DefinitionData::get(
definition)->formats)) {
161 maxId = qMax(maxId, format.id());
164 d->htmlStyles.clear();
166 d->htmlStyles.resize(maxId + 1);
169 for (
const auto &
definition : std::as_const(definitions)) {
170 for (
const auto &format : std::as_const(DefinitionData::get(
definition)->formats)) {
171 auto &buffer = d->htmlStyles[format.id()];
173 const auto textColor = useSelectedText ? format.selectedTextColor(
theme).rgba() : format.textColor(
theme).rgba();
174 if (textColor && textColor != mainTextColor) {
175 buffer += QStringLiteral(
"color:") + HtmlColor(textColor).sv() + u
';';
177 const auto bgColor = useSelectedText ? format.selectedBackgroundColor(
theme).rgba() : format.backgroundColor(
theme).rgba();
178 if (bgColor && bgColor != mainBgColor) {
179 buffer += QStringLiteral(
"background-color:") + HtmlColor(bgColor).sv() + u
';';
181 if (format.isBold(
theme)) {
182 buffer += QStringLiteral(
"font-weight:bold;");
184 if (format.isItalic(
theme)) {
185 buffer += QStringLiteral(
"font-style:italic;");
187 if (format.isUnderline(
theme)) {
188 buffer += QStringLiteral(
"text-decoration:underline;");
190 if (format.isStrikeThrough(
theme)) {
191 buffer += QStringLiteral(
"text-decoration:line-through;");
194 if (!buffer.isEmpty()) {
195 buffer.insert(0, QStringLiteral(
"<span style=\""));
197 buffer.back() = u
'"';
204 *d->out <<
"<!DOCTYPE html>\n";
205 *d->out <<
"<html><head>\n";
206 *d->out <<
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n";
207 *d->out <<
"<title>" << htmlTitle <<
"</title>\n";
208 *d->out <<
"<meta name=\"generator\" content=\"KF5::SyntaxHighlighting - Definition (" <<
definition.name() <<
") - Theme (" <<
theme.name() <<
")\"/>\n";
209 *d->out <<
"</head><body";
210 *d->out <<
" style=\"background-color:" << HtmlColor(mainBgColor).sv();
211 *d->out <<
";color:" << HtmlColor(mainTextColor).sv();
212 *d->out <<
"\"><pre>\n";
215 while (in.readLineInto(&d->currentLine)) {
220 *d->out <<
"</pre></body></html>\n";
227void HtmlHighlighter::applyFormat(
int offset,
int length,
const Format &format)
233 Q_D(HtmlHighlighter);
235 auto const &htmlStyle = d->htmlStyles[format.
id()];
237 if (!htmlStyle.isEmpty()) {
238 *d->out << htmlStyle;
241 for (QChar ch : QStringView(d->currentLine).sliced(offset, length)) {
243 *d->out << QStringLiteral(
"<");
245 *d->out << QStringLiteral(
"&");
250 if (!htmlStyle.isEmpty()) {
251 *d->out << QStringLiteral(
"</span>");
Abstract base class for highlighters.
Theme theme() const
Returns the currently selected theme for highlighting.
Definition definition() const
Returns the syntax definition used for highlighting.
State highlightLine(QStringView text, const State &state)
Highlight the given line.
EditorColorRole
Editor color roles, used to paint line numbers, editor background etc.
@ BackgroundColor
Background color for the editing area.
@ TextSelection
Background color for selected text.
@ Normal
Default text style for normal text and source code without special highlighting.
Syntax highlighting engine for Kate syntax definitions.
bool isEmpty() const const
QString toHtmlEscaped() const const