diff --git a/src/backends/julia/juliabackend.kcfg b/src/backends/julia/juliabackend.kcfg --- a/src/backends/julia/juliabackend.kcfg +++ b/src/backends/julia/juliabackend.kcfg @@ -12,5 +12,17 @@ QUrl::fromLocalFile(QStandardPaths::findExecutable(QLatin1String("julia"))) + + + true + + + + + + + + svg + diff --git a/src/backends/julia/juliaexpression.h b/src/backends/julia/juliaexpression.h --- a/src/backends/julia/juliaexpression.h +++ b/src/backends/julia/juliaexpression.h @@ -31,4 +31,9 @@ virtual void evaluate() override; virtual void interrupt() override; void finalize(); + +private: + QString m_plot_filename; + + bool checkPlotShowingCommands(); }; diff --git a/src/backends/julia/juliaexpression.cpp b/src/backends/julia/juliaexpression.cpp --- a/src/backends/julia/juliaexpression.cpp +++ b/src/backends/julia/juliaexpression.cpp @@ -19,8 +19,14 @@ */ #include "juliaexpression.h" +#include +#include + +#include "settings.h" #include "juliasession.h" +#include "juliakeywords.h" #include "textresult.h" +#include "imageresult.h" JuliaExpression::JuliaExpression(Cantor::Session *session) : Cantor::Expression(session) @@ -30,7 +36,28 @@ void JuliaExpression::evaluate() { setStatus(Cantor::Expression::Computing); - dynamic_cast(session())->runExpression(this); + auto juliaSession = dynamic_cast(session()); + + m_plot_filename.clear(); + if (juliaSession->integratePlots() and checkPlotShowingCommands()) { + QStringList inlinePlotFormats; + inlinePlotFormats << QLatin1String("svg"); + inlinePlotFormats << QLatin1String("eps"); + inlinePlotFormats << QLatin1String("png"); + + auto inlinePlotFormat = + inlinePlotFormats[JuliaSettings::inlinePlotFormat()]; + m_plot_filename = QDir::tempPath() + + QString::fromLatin1("/cantor-julia-export-%1.%2") + .arg(QUuid::createUuid().toString()).arg(inlinePlotFormat); + + QString saveFigCommand = + QString::fromLatin1("\nGR.savefig(\"%1\")\n").arg(m_plot_filename); + + setCommand(command().append(saveFigCommand)); + } + + juliaSession->runExpression(this); } void JuliaExpression::finalize() @@ -44,7 +71,14 @@ setResult(new Cantor::TextResult(juliaSession->getOutput())); setStatus(Cantor::Expression::Error); } else { - setResult(new Cantor::TextResult(juliaSession->getOutput())); + if (not m_plot_filename.isEmpty() + and QFileInfo(m_plot_filename).exists()) { + setResult( + new Cantor::ImageResult(QUrl::fromLocalFile(m_plot_filename))); + QDir().remove(m_plot_filename); + } else { + setResult(new Cantor::TextResult(juliaSession->getOutput())); + } setStatus(Cantor::Expression::Done); } } @@ -54,4 +88,15 @@ setStatus(Cantor::Expression::Interrupted); } +bool JuliaExpression::checkPlotShowingCommands() +{ + for (auto showingCommand : + JuliaKeywords::instance()->plotShowingCommands()) { + if (command().contains(showingCommand + QLatin1String("("))) { + return true; + } + } + return false; +} + #include "juliaexpression.moc" diff --git a/src/backends/julia/juliakeywords.h b/src/backends/julia/juliakeywords.h --- a/src/backends/julia/juliakeywords.h +++ b/src/backends/julia/juliakeywords.h @@ -27,6 +27,10 @@ static JuliaKeywords *instance(); const QStringList &keywords() const { return m_keywords; } + const QStringList &plotShowingCommands() const + { + return m_plotShowingCommands; + } const QStringList &variables() const { return m_variables; } const QStringList &removedVariables() const { return m_removedVariables; } @@ -40,6 +44,7 @@ private: QStringList m_keywords; + QStringList m_plotShowingCommands; QStringList m_variables; QStringList m_removedVariables; QStringList m_functions; diff --git a/src/backends/julia/juliakeywords.cpp b/src/backends/julia/juliakeywords.cpp --- a/src/backends/julia/juliakeywords.cpp +++ b/src/backends/julia/juliakeywords.cpp @@ -33,6 +33,7 @@ inst->loadFromFile(); qSort(inst->m_keywords); qSort(inst->m_variables); + qSort(inst->m_plotShowingCommands); } return inst; @@ -61,7 +62,8 @@ const QStringRef name = xml.name(); if (name == QLatin1String("keywords") - or name == QLatin1String("variables")) { + or name == QLatin1String("variables") + or name == QLatin1String("plot_showing_commands")) { while (xml.readNextStartElement()) { Q_ASSERT( xml.isStartElement() and xml.name() == QLatin1String("word") @@ -73,6 +75,8 @@ m_keywords << text; } else if (name == QLatin1String("variables")) { m_variables << text; + } else if (name == QLatin1String("plot_showing_commands")) { + m_plotShowingCommands << text; } } } else { diff --git a/src/backends/julia/juliasession.h b/src/backends/julia/juliasession.h --- a/src/backends/julia/juliasession.h +++ b/src/backends/julia/juliasession.h @@ -54,6 +54,8 @@ virtual QSyntaxHighlighter *syntaxHighlighter(QObject *parent); virtual QAbstractItemModel *variableModel() override; + bool integratePlots(); + Q_SIGNALS: void updateHighlighter(); diff --git a/src/backends/julia/juliasession.cpp b/src/backends/julia/juliasession.cpp --- a/src/backends/julia/juliasession.cpp +++ b/src/backends/julia/juliasession.cpp @@ -98,6 +98,13 @@ listVariables(); + // Plots integration + if (integratePlots()) { + runJuliaCommand( + QLatin1String("import GR; ENV[\"GKS_WSTYPE\"] = \"nul\"") + ); + } + emit ready(); } @@ -322,4 +329,11 @@ return m_variableModel; } + +bool JuliaSession::integratePlots() +{ + return JuliaSettings::integratePlots(); +} + + #include "juliasession.moc" diff --git a/src/backends/julia/keywords.xml b/src/backends/julia/keywords.xml --- a/src/backends/julia/keywords.xml +++ b/src/backends/julia/keywords.xml @@ -41,4 +41,23 @@ using while + + contourf + contour + grid3d + grid + histogram + imshow + plot3 + plot + polar + polyline3d + polyline + polymarker3d + polymarker + scatter3 + scatter + show + surface + diff --git a/src/backends/julia/settings.ui b/src/backends/julia/settings.ui --- a/src/backends/julia/settings.ui +++ b/src/backends/julia/settings.ui @@ -4,6 +4,19 @@ + + + Qt::Vertical + + + + 20 + 40 + + + + + @@ -17,6 +30,56 @@ + + + + Integrate Plots in Worksheet (start a new session when changed) + + + + + + + + + Inline Plots Intermediate Format: + + + + + + + + svg + + + + + eps + + + + + png + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + +