diff --git a/src/backends/sage/sageexpression.cpp b/src/backends/sage/sageexpression.cpp index 524d2f20..b3b49cd1 100644 --- a/src/backends/sage/sageexpression.cpp +++ b/src/backends/sage/sageexpression.cpp @@ -1,264 +1,265 @@ /* 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) { stripped = stripped.toHtmlEscaped(); + stripped.replace(QLatin1Char(' '), QLatin1String(" ")); stripped.replace(QLatin1Char('\n'), QLatin1String("
\n")); //make things quoted in `` `` bold stripped.replace(QRegExp(QLatin1String("``([^`]*)``")), QLatin1String("\\1")); addResult(new Cantor::HelpResult(stripped, true)); } else { Cantor::TextResult* result=new Cantor::TextResult(stripped); 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/helpresult.cpp b/src/lib/helpresult.cpp index f294e835..3a54b68f 100644 --- a/src/lib/helpresult.cpp +++ b/src/lib/helpresult.cpp @@ -1,79 +1,80 @@ /* 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, bool isHtml) : d(new HelpResultPrivate) { QString html; if (!isHtml) { html = text.toHtmlEscaped(); + html.replace(QLatin1Char(' '), QLatin1String(" ")); 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")); 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); }