Skip to content

Commit 913f557

Browse files
committed
AnsiToHTML.cpp: remove HTML usage
We no longer use HTML to create logs. Lets do a simple cleanup.
1 parent f9bb2d0 commit 913f557

3 files changed

Lines changed: 12 additions & 193 deletions

File tree

src/AnsiToHTML.cpp

Lines changed: 2 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void applyAnsiCodeToFormat(QTextCharFormat &fmt, const QString &codeStr) {
8888
break;
8989
case 2:
9090
fmt.setFontWeight(QFont::Normal);
91-
break; // Faint fallback
91+
break;
9292
case 3:
9393
fmt.setFontItalic(true);
9494
break;
@@ -185,15 +185,12 @@ void insertLinkifiedText(QTextCursor &cursor, const QString &text,
185185
}
186186
}
187187

188-
void appendAnsiHtml(QTextEdit *edit, const QString &ansiText) {
188+
void appendAnsiText(QTextEdit *edit, const QString &ansiText) {
189189
auto cursor = edit->textCursor();
190190
cursor.movePosition(QTextCursor::End);
191191

192192
static QRegularExpression ansiRegex("\x1b\\[([0-9;]*)m");
193193
static QRegularExpression removeRegex("\x1b\\[K");
194-
static QRegularExpression urlRegex(R"((https?|file)://[^\s<>()]+)");
195-
static QRegularExpression pathRegex(
196-
R"((([A-Za-z]:[\\/][\w\-.+\\/ ]+|~?/?[\w\-.+/]+)\.[a-zA-Z0-9+_-]{1,8})(:\d+)?(:\d+)?(:)?)");
197194

198195
auto cleanedText = ansiText;
199196
cleanedText.remove(removeRegex);
@@ -235,170 +232,6 @@ void appendAnsiHtml(QTextEdit *edit, const QString &ansiText) {
235232
edit->ensureCursorVisible();
236233
}
237234

238-
auto appendAnsiHtml2(QTextEdit *edit, const QString &ansiText) -> void {
239-
edit->moveCursor(QTextCursor::End);
240-
241-
#if 1
242-
auto html = ansiToHtml(ansiText, true);
243-
edit->insertHtml(ansiText);
244-
#else
245-
edit->insertPlainText(ansiText);
246-
#endif
247-
edit->moveCursor(QTextCursor::End);
248-
edit->ensureCursorVisible();
249-
}
250-
251-
auto static isInsideAnchor(const QString &html, int pos) -> bool {
252-
auto open = html.lastIndexOf("<a ", pos, Qt::CaseInsensitive);
253-
auto close = html.lastIndexOf("</a>", pos, Qt::CaseInsensitive);
254-
return open != -1 && (close == -1 || open > close);
255-
};
256-
257-
auto linkifyFileNames(const QString &html) -> QString {
258-
auto pathRegex = QRegularExpression(
259-
R"((([A-Za-z]:[\\/][\w\-.+\\/ ]+|~?/?[\w\-.+/]+)\.[a-zA-Z0-9+_-]{1,8})(:\d+)?(:\d+)?(:)?)");
260-
261-
auto result = QString{};
262-
auto lastPos = 0;
263-
auto it = pathRegex.globalMatch(html);
264-
265-
while (it.hasNext()) {
266-
auto match = it.next();
267-
auto start = match.capturedStart();
268-
auto end = match.capturedEnd();
269-
auto fullMatch = match.captured(0);
270-
auto filePart = match.captured(1);
271-
auto line = match.captured(3).mid(1);
272-
auto column = match.captured(4).mid(1);
273-
auto insideAnchor = isInsideAnchor(html, start);
274-
275-
result += html.mid(lastPos, start - lastPos);
276-
if (insideAnchor) {
277-
result += fullMatch;
278-
} else {
279-
auto fragment = QString{};
280-
auto urlPath = filePart;
281-
// Convert backslashes to slashes for file:// URLs
282-
urlPath.replace("\\", "/");
283-
auto fileUrl = QUrl::fromLocalFile(urlPath);
284-
285-
if (!line.isEmpty()) {
286-
fragment += line;
287-
}
288-
if (!column.isEmpty()) {
289-
if (!fragment.isEmpty()) {
290-
fragment += ",";
291-
}
292-
fragment += column;
293-
}
294-
if (!fragment.isEmpty()) {
295-
fileUrl.setFragment(fragment);
296-
}
297-
auto link =
298-
QString("<a href=\"%1\">%2</a>").arg(fileUrl.toString(), fullMatch.toHtmlEscaped());
299-
result += link;
300-
}
301-
lastPos = end;
302-
}
303-
result += html.mid(lastPos);
304-
return result;
305-
}
306-
307-
QString linkifyUrls(const QString &html) {
308-
static const QRegularExpression urlRegex(
309-
R"((([a-z][a-z0-9+\-.]*://[^\s<>"']+)|www\.[^\s<>"']+))",
310-
QRegularExpression::CaseInsensitiveOption);
311-
312-
auto output = QString{};
313-
auto lastPos = 0;
314-
auto matchIter = urlRegex.globalMatch(html);
315-
while (matchIter.hasNext()) {
316-
auto match = matchIter.next();
317-
auto start = match.capturedStart();
318-
auto end = match.capturedEnd();
319-
320-
if (isInsideAnchor(html, start)) {
321-
continue;
322-
}
323-
output += html.mid(lastPos, start - lastPos);
324-
auto url = match.captured(0);
325-
// Only prepend http:// if the url starts with www.
326-
auto href = url.startsWith("www.", Qt::CaseInsensitive) ? "http://" + url : url;
327-
output += "<a href=\"" + href.toHtmlEscaped() + "\">" + url.toHtmlEscaped() + "</a>";
328-
lastPos = end;
329-
}
330-
output += html.mid(lastPos);
331-
return output;
332-
}
333-
334-
auto ansiToHtml(const QString &ansiText, bool linkifyFiles) -> QString {
335-
static auto ansiRegex = QRegularExpression("\x1b\\[([0-9;]*)m");
336-
static auto removeRegex = QRegularExpression("\x1b\\[K");
337-
338-
auto htmlText = ansiText;
339-
htmlText.replace("&", "&amp;");
340-
htmlText.replace("<", "&lt;");
341-
htmlText.replace(">", "&gt;");
342-
htmlText.replace(" ", "&nbsp;");
343-
htmlText.replace("\n", "<br>\n");
344-
345-
htmlText.remove(removeRegex);
346-
347-
auto ansiToCss = QMap<QString, QString>{
348-
{"30", "black"}, {"31", "red"}, {"32", "green"}, {"33", "yellow"},
349-
{"34", "blue"}, {"35", "magenta"}, {"36", "cyan"}, {"37", "white"},
350-
{"90", "gray"}, {"91", "lightcoral"}, {"92", "lightgreen"}, {"93", "khaki"},
351-
{"94", "lightskyblue"}, {"95", "violet"}, {"96", "lightcyan"}, {"97", "whitesmoke"},
352-
};
353-
354-
auto lastPos = 0;
355-
auto it = ansiRegex.globalMatch(htmlText);
356-
QStringList openTags;
357-
QString result;
358-
359-
while (it.hasNext()) {
360-
auto match = it.next();
361-
auto codes = match.captured(1).split(';');
362-
auto isReset = (codes.isEmpty() || codes.contains("0"));
363-
364-
result += htmlText.mid(lastPos, match.capturedStart() - lastPos);
365-
if (isReset) {
366-
while (!openTags.isEmpty()) {
367-
result += openTags.takeLast();
368-
}
369-
} else {
370-
auto style = QString{};
371-
for (auto const &code : std::as_const(codes)) {
372-
if (ansiToCss.contains(code)) {
373-
style += QString("color:%1;").arg(ansiToCss.value(code));
374-
} else if (code == "1") {
375-
style += "font-weight:bold;";
376-
}
377-
// Add more style handlers here if needed
378-
}
379-
if (!style.isEmpty()) {
380-
result += QString("<span style=\"%1\">").arg(style);
381-
openTags.append("</span>");
382-
}
383-
}
384-
385-
lastPos = match.capturedEnd();
386-
}
387-
388-
result += htmlText.mid(lastPos);
389-
while (!openTags.isEmpty()) {
390-
result += openTags.takeLast();
391-
}
392-
393-
result = linkifyUrls(result);
394-
395-
if (linkifyFiles) {
396-
result = linkifyFileNames(result);
397-
}
398-
399-
return result + "</br>";
400-
}
401-
402235
auto removeAnsiEscapeCodes(const QString &input) -> QString {
403236
static const QRegularExpression ansiRegex(
404237
R"((\x1B\[[0-9;?]*[ -/]*[@-~])|(\x1B\]8;[^\x07\x1B]*[\x07\x1B\\]))");

src/AnsiToHTML.hpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,11 @@ class QString;
1616
/// Returns true, if a string is binary, or plain text
1717
auto isPlainText(const QString &str) -> bool;
1818

19-
// UNUSED: default theme for console forerground colors
20-
auto defaultFgColorMap() -> const QMap<int, QString> &;
21-
// UNUSED: default theme for console background colors
22-
auto defaultBgColorMap() -> const QMap<int, QString> &;
23-
2419
/// Helper function, appends plain text to to a QTextEdit
2520
auto appendAscii(QTextEdit *edit, const QString &plainText) -> void;
2621

2722
/// Helper function, converts ANSI escaped text to HTML and appends it to a QTextEdit
28-
auto appendAnsiHtml(QTextEdit *edit, const QString &ansiText) -> void;
29-
30-
/// Convert an HTML string, linking all filenames inside "<a href>"
31-
auto linkifyFileNames(const QString &html) -> QString;
32-
33-
/// Convert an HTML string, linking all URLS inside "<a href>"
34-
auto linkifyUrls(const QString &html) -> QString;
35-
36-
/// Convert ANSI escaped string, to HTML
37-
auto ansiToHtml(const QString &ansiText, bool linkifyFiles) -> QString;
23+
auto appendAnsiText(QTextEdit *edit, const QString &ansiText) -> void;
3824

3925
/// Convert a text containing ANSI escaped code to raw text.
4026
auto removeAnsiEscapeCodes(const QString &input) -> QString;

src/plugins/ProjectManager/ProjectManagerPlg.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ void ProjectManagerPlugin::on_client_merged(qmdiHost *host) {
436436
&runProcess, &QProcess::finished, this,
437437
[this](int exitCode, QProcess::ExitStatus exitStatus) {
438438
auto output = QString("[code=%1, status=%2]").arg(exitCode).arg(str(exitStatus));
439-
appendAnsiHtml(outputPanel->commandOuput, output);
439+
appendAnsiText(outputPanel->commandOuput, output);
440440
getManager()->showPanels(Qt::BottomDockWidgetArea);
441441
outputDock->raise();
442442
outputDock->show();
@@ -481,7 +481,7 @@ void ProjectManagerPlugin::on_client_merged(qmdiHost *host) {
481481
});
482482
connect(&runProcess, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
483483
auto output = QString("\n[error: code=%1]").arg((int)error);
484-
appendAnsiHtml(outputPanel->commandOuput, output);
484+
appendAnsiText(outputPanel->commandOuput, output);
485485
qWarning() << "Process error occurred:" << error;
486486
qWarning() << "Error string:" << runProcess.errorString();
487487
});
@@ -893,8 +893,8 @@ void ProjectManagerPlugin::do_runExecutable(const ExecutableInfo *info) {
893893

894894
workingDirectory = project->expand(workingDirectory);
895895
outputPanel->commandOuput->clear();
896-
appendAnsiHtml(outputPanel->commandOuput, "cd " + QDir::toNativeSeparators(workingDirectory));
897-
appendAnsiHtml(outputPanel->commandOuput, QString("\n%1\n").arg(executablePath));
896+
appendAnsiText(outputPanel->commandOuput, "cd " + QDir::toNativeSeparators(workingDirectory));
897+
appendAnsiText(outputPanel->commandOuput, QString("\n%1\n").arg(executablePath));
898898
outputDock->raise();
899899
outputDock->show();
900900

@@ -925,7 +925,7 @@ void ProjectManagerPlugin::do_runTask(const TaskInfo *task) {
925925
if (!task->commands.contains(platform) || task->commands.value(platform).isEmpty()) {
926926
auto msg = QString("do_runTask: No valid commands for platform ") + platform;
927927
qWarning() << msg;
928-
appendAnsiHtml(outputPanel->commandOuput, msg + "\n");
928+
appendAnsiText(outputPanel->commandOuput, msg + "\n");
929929
return;
930930
}
931931

@@ -946,16 +946,16 @@ void ProjectManagerPlugin::do_runTask(const TaskInfo *task) {
946946
outputDock->raise();
947947
outputDock->show();
948948
outputPanel->commandOuput->clear();
949-
appendAnsiHtml(outputPanel->commandOuput, "cd " + workingDirectory + "\n");
949+
appendAnsiText(outputPanel->commandOuput, "cd " + workingDirectory + "\n");
950950

951951
auto env = QProcessEnvironment::systemEnvironment();
952952
auto program = QString();
953953
auto arguments = QStringList();
954954

955955
if (!kit) {
956956
auto [interpreter, command] = getCommandInterpreter(taskCommand);
957-
appendAnsiHtml(outputPanel->commandOuput, interpreter + " " + command.join(" ") + "\n");
958-
appendAnsiHtml(outputPanel->commandOuput, "Commands: " + taskCommand + "\n");
957+
appendAnsiText(outputPanel->commandOuput, interpreter + " " + command.join(" ") + "\n");
958+
appendAnsiText(outputPanel->commandOuput, "Commands: " + taskCommand + "\n");
959959
program = interpreter;
960960
arguments = command;
961961
} else {
@@ -1077,7 +1077,7 @@ auto ProjectManagerPlugin::processBuildOutput(const QString &line) -> void {
10771077

10781078
auto plaintext = removeAnsiEscapeCodes(fixedAnsi);
10791079
auto project = this->getCurrentConfig();
1080-
appendAnsiHtml(this->outputPanel->commandOuput, fixedAnsi);
1080+
appendAnsiText(this->outputPanel->commandOuput, fixedAnsi);
10811081
auto sourceDir = project->sourceDir;
10821082
auto buildDir = project->expand(project->buildDir);
10831083
this->projectIssues->processLine(plaintext, lineNumber, sourceDir, buildDir);

0 commit comments

Comments
 (0)