File indexing completed on 2023-05-30 10:40:16
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2019 Sirgienko Nikita <warquark@gmail.com> 0004 */ 0005 0006 #include "htmlresult.h" 0007 0008 #include <QFile> 0009 #include <QTextStream> 0010 #include <QJsonArray> 0011 #include <QJsonObject> 0012 #include <QJsonDocument> 0013 0014 #include "jupyterutils.h" 0015 0016 using namespace Cantor; 0017 0018 class Cantor::HtmlResultPrivate 0019 { 0020 public: 0021 QString html; 0022 QString plain; 0023 std::map<QString, QJsonValue> alternatives; // Useful only for Jupyter, it think 0024 Cantor::HtmlResult::Format format{Cantor::HtmlResult::Html}; 0025 }; 0026 0027 HtmlResult::HtmlResult(const QString& html, const QString& plain, const std::map<QString, QJsonValue>& alternatives) : d(new HtmlResultPrivate()) 0028 { 0029 d->html = html; 0030 d->plain = plain; 0031 d->alternatives = alternatives; 0032 } 0033 0034 HtmlResult::~HtmlResult() 0035 { 0036 delete d; 0037 } 0038 0039 QString HtmlResult::toHtml() 0040 { 0041 switch(d->format) 0042 { 0043 case HtmlResult::Html: 0044 return d->html; 0045 0046 case HtmlResult::HtmlSource: 0047 return QStringLiteral("<code><pre>") + d->html.toHtmlEscaped() + QStringLiteral("</pre></code>"); 0048 0049 case HtmlResult::PlainAlternative: 0050 return QStringLiteral("<pre>") + d->plain.toHtmlEscaped() + QStringLiteral("</pre>"); 0051 0052 default: 0053 return QString(); 0054 } 0055 } 0056 0057 QVariant Cantor::HtmlResult::data() 0058 { 0059 return d->html; 0060 } 0061 0062 QString Cantor::HtmlResult::plain() 0063 { 0064 return d->plain; 0065 } 0066 0067 void Cantor::HtmlResult::setFormat(HtmlResult::Format format) 0068 { 0069 d->format = format; 0070 } 0071 0072 HtmlResult::Format Cantor::HtmlResult::format() 0073 { 0074 return d->format; 0075 } 0076 0077 int Cantor::HtmlResult::type() 0078 { 0079 return HtmlResult::Type; 0080 } 0081 0082 QString Cantor::HtmlResult::mimeType() 0083 { 0084 return QStringLiteral("text/html"); 0085 } 0086 0087 QDomElement Cantor::HtmlResult::toXml(QDomDocument& doc) 0088 { 0089 QDomElement e=doc.createElement(QStringLiteral("Result")); 0090 e.setAttribute(QStringLiteral("type"), QStringLiteral("html")); 0091 switch(d->format) 0092 { 0093 case HtmlResult::HtmlSource: 0094 e.setAttribute(QStringLiteral("format"), QStringLiteral("htmlSource")); 0095 break; 0096 0097 case HtmlResult::PlainAlternative: 0098 e.setAttribute(QStringLiteral("format"), QStringLiteral("plain")); 0099 break; 0100 0101 // Html format used by default, so don't set it 0102 default: 0103 break; 0104 } 0105 0106 QDomElement plainE = doc.createElement(QStringLiteral("Plain")); 0107 plainE.appendChild(doc.createTextNode(d->plain)); 0108 e.appendChild(plainE); 0109 0110 QDomElement htmlE = doc.createElement(QStringLiteral("Html")); 0111 htmlE.appendChild(doc.createTextNode(d->html)); 0112 e.appendChild(htmlE); 0113 0114 for (auto iter = d->alternatives.begin(); iter != d->alternatives.end(); iter++) 0115 { 0116 QJsonDocument jsonDoc; 0117 QJsonObject obj; 0118 obj.insert(QLatin1String("root"), iter->second); 0119 jsonDoc.setObject(obj); 0120 0121 QDomElement content = doc.createElement(QStringLiteral("Alternative")); 0122 content.setAttribute(QStringLiteral("key"), iter->first); 0123 content.appendChild(doc.createTextNode(QString::fromUtf8(jsonDoc.toJson()))); 0124 e.appendChild(content); 0125 } 0126 0127 return e; 0128 } 0129 0130 QJsonValue Cantor::HtmlResult::toJupyterJson() 0131 { 0132 QJsonObject root; 0133 if (executionIndex() != -1) 0134 { 0135 root.insert(QLatin1String("output_type"), QLatin1String("execute_result")); 0136 root.insert(QLatin1String("execution_count"), executionIndex()); 0137 } 0138 else 0139 root.insert(QLatin1String("output_type"), QLatin1String("display_data")); 0140 0141 0142 QJsonObject data; 0143 data.insert(QLatin1String("text/html"), JupyterUtils::toJupyterMultiline(d->html)); 0144 if (!d->plain.isEmpty()) 0145 data.insert(QLatin1String("text/plain"), JupyterUtils::toJupyterMultiline(d->plain)); 0146 0147 for (auto iter = d->alternatives.begin(); iter != d->alternatives.end(); iter++) 0148 data.insert(iter->first, iter->second); 0149 0150 root.insert(QLatin1String("data"), data); 0151 0152 root.insert(QLatin1String("metadata"), jupyterMetadata()); 0153 0154 return root; 0155 } 0156 0157 void Cantor::HtmlResult::save(const QString& filename) 0158 { 0159 QFile file(filename); 0160 0161 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) 0162 return; 0163 0164 QTextStream stream(&file); 0165 0166 stream<<d->html; 0167 0168 file.close(); 0169 }