diff --git a/src/backends/sage/sageexpression.cpp b/src/backends/sage/sageexpression.cpp index 3945101e..524d2f20 100644 --- a/src/backends/sage/sageexpression.cpp +++ b/src/backends/sage/sageexpression.cpp @@ -1,267 +1,264 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "sageexpression.h" #include "sagesession.h" #include "textresult.h" #include "imageresult.h" #include "animationresult.h" #include "helpresult.h" #include #include #include #include SageExpression::SageExpression( Cantor::Session* session, bool internal ) : Cantor::Expression(session, internal), m_isHelpRequest(false), m_promptCount(0), m_syntaxError(false) { } void SageExpression::evaluate() { m_imagePath.clear(); m_isHelpRequest=false; //check if this is a ?command or help command if( command().startsWith(QLatin1Char('?')) || command().endsWith(QLatin1Char('?')) || command().contains(QLatin1String("help(")) ) m_isHelpRequest=true; //coun't how many newlines are in the command, //as sage will output one "sage: " or "....:" for //each. m_promptCount=command().count(QLatin1Char('\n'))+2; session()->enqueueExpression(this); } void SageExpression::interrupt() { qDebug()<<"interrupting"; setStatus(Cantor::Expression::Interrupted); } void SageExpression::parseOutput(const QString& text) { if (m_syntaxError) { setErrorMessage(i18n("Syntax Error")); setStatus(Cantor::Expression::Error); return; } QString output=text; //remove carriage returns, we only use \n internally output.remove(QLatin1Char('\r')); //replace appearing backspaces, as they mess the whole output up output.remove(QRegExp(QLatin1String(".\b"))); //replace Escape sequences (only tested with `ls` command) const QChar ESC(0x1b); output.remove(QRegExp(QString(ESC)+QLatin1String("\\][^\a]*\a"))); const QString promptRegexpBase(QLatin1String("(^|\\n)%1")); const QRegExp promptRegexp(promptRegexpBase.arg(QRegExp::escape(QLatin1String(SageSession::SagePrompt)))); const QRegExp altPromptRegexp(promptRegexpBase.arg(QRegExp::escape(QLatin1String(SageSession::SageAlternativePrompt)))); bool endsWithAlternativePrompt=output.endsWith(QLatin1String(SageSession::SageAlternativePrompt)); //remove all prompts. we do this in a loop, because after we removed the first prompt, //there could be a second one, that isn't matched by promptRegexp in the first run, because //it originally isn't at the beginning of a line. int index=-1, index2=-1; while ( (index=output.indexOf(promptRegexp)) != -1 || (index2=output.indexOf(altPromptRegexp)) != -1 ) { qDebug()<<"got prompt"<(session())->sendInputToProcess(QLatin1String(")\n")); m_syntaxError = true; } else { m_outputCache=m_outputCache.trimmed(); evalFinished(); } } } void SageExpression::parseError(const QString& text) { qDebug()<<"error"; setErrorMessage(text); setStatus(Cantor::Expression::Error); } void SageExpression::addFileResult( const QString& path ) { QUrl url = QUrl::fromLocalFile(path); QMimeDatabase db; QMimeType type = db.mimeTypeForUrl(url); if(m_imagePath.isEmpty()||type.name().contains(QLatin1String("image"))||path.endsWith(QLatin1String(".png"))||path.endsWith(QLatin1String(".gif"))) { m_imagePath=path; } } void SageExpression::evalFinished() { qDebug()<<"evaluation finished"; qDebug()<")); const bool isLatex=m_outputCache.contains(QLatin1String("\\newcommand{\\Bold}")); //Check if it's latex stuff if(isLatex) //It's latex stuff so encapsulate it into an eqnarray environment { stripped.prepend(QLatin1String("\\begin{eqnarray*}")); stripped.append(QLatin1String("\\end{eqnarray*}")); } //strip html tags if(isHtml) { stripped.remove( QRegExp( QLatin1String("<[a-zA-Z\\/][^>]*>") ) ); } + if (stripped.endsWith(QLatin1Char('\n'))) stripped.chop(1); if (m_isHelpRequest) { - //Escape whitespace - stripped.replace( QLatin1Char(' '), QLatin1String(" ")); + stripped = stripped.toHtmlEscaped(); + stripped.replace(QLatin1Char('\n'), QLatin1String("
\n")); //make things quoted in `` `` bold stripped.replace(QRegExp(QLatin1String("``([^`]*)``")), QLatin1String("\\1")); - result=new Cantor::HelpResult(stripped); + addResult(new Cantor::HelpResult(stripped, true)); } else { - result=new Cantor::TextResult(stripped); + Cantor::TextResult* result=new Cantor::TextResult(stripped); + if(isLatex) + result->setFormat(Cantor::TextResult::LatexFormat); + addResult(result); } - - if(isLatex) - result->setFormat(Cantor::TextResult::LatexFormat); - - addResult(result); } if (hasImage) { QMimeDatabase db; QMimeType type = db.mimeTypeForUrl(QUrl::fromLocalFile(m_imagePath)); if(type.inherits(QLatin1String("image/gif"))) addResult( new Cantor::AnimationResult(QUrl::fromLocalFile(m_imagePath ),i18n("Result of %1" , command() ) ) ); else addResult( new Cantor::ImageResult( QUrl::fromLocalFile(m_imagePath ),i18n("Result of %1" , command() ) ) ); } setStatus(Cantor::Expression::Done); } void SageExpression::onProcessError(const QString& msg) { QString errMsg=i18n("%1\nThe last output was: \n %2", msg, m_outputCache.trimmed()); setErrorMessage(errMsg); setStatus(Cantor::Expression::Error); } QString SageExpression::additionalLatexHeaders() { //The LaTeX sage needs the amsmath package and some specific macros. //So include them in the header. //More about the macros requirement in bug #312738 return QLatin1String("\\usepackage{amsmath}\n" \ "\\newcommand{\\ZZ}{\\Bold{Z}}\n" \ "\\newcommand{\\NN}{\\Bold{N}}\n" \ "\\newcommand{\\RR}{\\Bold{R}}\n" \ "\\newcommand{\\CC}{\\Bold{C}}\n" \ "\\newcommand{\\QQ}{\\Bold{Q}}\n" \ "\\newcommand{\\QQbar}{\\overline{\\QQ}}\n" \ "\\newcommand{\\GF}[1]{\\Bold{F}_{#1}}\n" \ "\\newcommand{\\Zp}[1]{\\ZZ_{#1}}\n" \ "\\newcommand{\\Qp}[1]{\\QQ_{#1}}\n" \ "\\newcommand{\\Zmod}[1]{\\ZZ/#1\\ZZ}\n" \ "\\newcommand{\\CDF}{\\Bold{C}}\n" \ "\\newcommand{\\CIF}{\\Bold{C}}\n" \ "\\newcommand{\\CLF}{\\Bold{C}}\n" \ "\\newcommand{\\RDF}{\\Bold{R}}\n" \ "\\newcommand{\\RIF}{\\Bold{I} \\Bold{R}}\n"\ "\\newcommand{\\RLF}{\\Bold{R}}\n" \ "\\newcommand{\\CFF}{\\Bold{CFF}}\n"); } diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 2a6cad32..4d8fb480 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,91 +1,89 @@ set( cantor_LIB_SRCS session.cpp expression.cpp backend.cpp result.cpp textresult.cpp imageresult.cpp epsresult.cpp latexresult.cpp latexrenderer.cpp helpresult.cpp animationresult.cpp extension.cpp assistant.cpp completionobject.cpp syntaxhelpobject.cpp defaulthighlighter.cpp defaultvariablemodel.cpp panelplugin.cpp panelpluginhandler.cpp worksheetaccess.cpp directives/plotdirectives.cpp ) Set( cantor_LIB_HDRS cantor_macros.h #base classes backend.h session.h expression.h extension.h syntaxhelpobject.h completionobject.h #results animationresult.h epsresult.h helpresult.h imageresult.h latexresult.h result.h textresult.h #helper classes defaulthighlighter.h defaultvariablemodel.h worksheetaccess.h ) ki18n_wrap_ui(cantor_LIB_SRCS directives/axisrange.ui directives/plottitle.ui) kconfig_add_kcfg_files(cantor_LIB_SRCS settings.kcfgc) install(FILES cantor_libs.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) configure_file (config-cantorlib.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-cantorlib.h ) add_library( cantorlibs SHARED ${cantor_LIB_SRCS} ) generate_export_header(cantorlibs BASE_NAME cantor) kcoreaddons_desktop_to_json(cantorlibs cantor_assistant.desktop DEFAULT_SERVICE_TYPE) kcoreaddons_desktop_to_json(cantorlibs cantor_backend.desktop DEFAULT_SERVICE_TYPE) kcoreaddons_desktop_to_json(cantorlibs cantor_panelplugin.desktop DEFAULT_SERVICE_TYPE) target_link_libraries( cantorlibs KF5::Completion KF5::IconThemes KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets KF5::Archive KF5::ConfigCore KF5::ConfigGui KF5::I18n KF5::XmlGui ${QT5_LIBRARIES} Qt5::Xml ) -set_target_properties( cantorlibs - PROPERTIES VERSION ${KDE_APPLICATIONS_VERSION} SOVERSION 19 -) +set_target_properties( cantorlibs PROPERTIES VERSION ${KDE_APPLICATIONS_VERSION} SOVERSION 20) install( TARGETS cantorlibs ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) install( FILES ${cantor_LIB_HDRS} DESTINATION ${KDE_INSTALL_INCLUDEDIR}/cantor COMPONENT Devel ) if(BUILD_TESTING) add_subdirectory(test) endif() diff --git a/src/lib/helpresult.cpp b/src/lib/helpresult.cpp index 8ae9147b..f294e835 100644 --- a/src/lib/helpresult.cpp +++ b/src/lib/helpresult.cpp @@ -1,44 +1,79 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "helpresult.h" using namespace Cantor; +class Cantor::HelpResultPrivate +{ +public: + HelpResultPrivate() = default; + ~HelpResultPrivate() = default; + + QString html; +}; -HelpResult::HelpResult(const QString& text) : TextResult(text) +HelpResult::HelpResult(const QString& text, bool isHtml) : d(new HelpResultPrivate) { + QString html; + if (!isHtml) + { + html = text.toHtmlEscaped(); + html.replace(QLatin1Char('\n'), QLatin1String("
\n")); + } + else + html = text; + d->html = html; } int HelpResult::type() { return HelpResult::Type; } QDomElement HelpResult::toXml(QDomDocument& doc) { + //No need to save results of a help request QDomElement e=doc.createElement(QLatin1String("Result")); e.setAttribute(QLatin1String("type"), QLatin1String("help")); - //No need to save results of a help request - QDomText txt=doc.createTextNode(QString()); - e.appendChild(txt); - return e; } + +QString HelpResult::toHtml() +{ + return d->html; +} + +QVariant HelpResult::data() +{ + return QVariant(d->html); +} + +QString HelpResult::mimeType() +{ + return QLatin1String("text/html"); +} + +void HelpResult::save(const QString& filename) +{ + //No need to save results of a help request + Q_UNUSED(filename); +} diff --git a/src/lib/helpresult.h b/src/lib/helpresult.h index 3622ad54..8422c91b 100644 --- a/src/lib/helpresult.h +++ b/src/lib/helpresult.h @@ -1,47 +1,56 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _HELPRESULT_H #define _HELPRESULT_H #include "textresult.h" namespace Cantor { /** this is basically a TextResult, just with a different Type so that the application can show it in another way than the normal results **/ -class CANTOR_EXPORT HelpResult : public TextResult +class HelpResultPrivate; +class CANTOR_EXPORT HelpResult: public Result { public: enum {Type=3}; - explicit HelpResult( const QString& text); + explicit HelpResult( const QString& text, bool isHtml=false); ~HelpResult() override = default; + QVariant data() override; + QString toHtml() override; + int type() override; + QString mimeType() override; QDomElement toXml(QDomDocument& doc) override; + void save(const QString& filename) override; + + private: + HelpResultPrivate* d; }; } #endif /* _HELPRESULT_H */