+
+ vector<string> tmp = getVectorFromString(out, "$$");
+ if (tmp.size() < 2)
+ return MathArray();
+
+ out = subst(tmp[1],"\\>", "");
+ lyxerr << "out: '" << out << "'" << endl;
+
+ // Ugly code that tries to make the result prettier
+
+ string::size_type i = out.find("\\mathchoice");
+ while (i != string::npos) {
+ string::size_type j = get_matching_brace(out, i + 12);
+ string::size_type k = get_matching_brace(out, j + 1);
+ k = get_matching_brace(out, k + 1);
+ k = get_matching_brace(out, k + 1);
+ string mid = out.substr(i + 13,j - i - 13);
+ if (mid.find("\\over") != string::npos)
+ mid = '{' + mid + '}';
+ out = out.substr(0,i)
+ + mid
+ + out.substr(k + 1);
+ //lyxerr << "out: " << out << endl;
+ i = out.find("\\mathchoice", i);
+ break;
+ }
+
+ i = out.find("\\over");
+ while (i != string::npos) {
+ string::size_type j = get_matching_brace_back(out, i - 1);
+ if (j == string::npos || j == 0) break;
+ string::size_type k = get_matching_brace(out, i + 5);
+ if (k == string::npos || k + 1 == out.size()) break;
+ out = out.substr(0,j - 1)
+ + "\\frac"
+ + out.substr(j,i - j)
+ + out.substr(i + 5,k - i - 4)
+ + out.substr(k + 2);
+ //lyxerr << "out: " << out << endl;
+ i = out.find("\\over", i + 4);
+ }
+ MathArray res;
+ mathed_parse_cell(res, out);
+ return res;
+ }
+
+
+ MathArray pipeThroughMaple(string const & extra, MathArray const & ar)
+ {
+ string header = "readlib(latex):\n";
+
+ // remove the \\it for variable names
+ //"#`latex/csname_font` := `\\it `:"
+ header +=
+ "`latex/csname_font` := ``:\n";
+
+ // export matrices in (...) instead of [...]
+ header +=
+ "`latex/latex/matrix` := "
+ "subs(`[`=`(`, `]`=`)`,"
+ "eval(`latex/latex/matrix`)):\n";
+
+ // replace \\cdots with proper '*'
+ header +=
+ "`latex/latex/*` := "
+ "subs(`\\,`=`\\cdot `,"
+ "eval(`latex/latex/*`)):\n";
+
+ // remove spurious \\noalign{\\medskip} in matrix output
+ header +=
+ "`latex/latex/matrix`:= "
+ "subs(`\\\\\\\\\\\\noalign{\\\\medskip}` = `\\\\\\\\`,"
+ "eval(`latex/latex/matrix`)):\n";
+
+ //"#`latex/latex/symbol` "
+ // " := subs((\\'_\\' = \\'`\\_`\\',eval(`latex/latex/symbol`)): ";
+
+ string trailer = "quit;";
+ ostringstream os;
+ MapleStream ms(os);
+ ms << ar;
+ string expr = os.str();
+ lyxerr << "ar: '" << ar << "'\n"
+ << "ms: '" << os.str() << "'" << endl;
+
+ for (int i = 0; i < 100; ++i) { // at most 100 attempts
+ // try to fix missing '*' the hard way by using mint
+ //
+ // ... > echo "1A;" | mint -i 1 -S -s -q
+ // on line 1: 1A;
+ // ^ syntax error -
+ // Probably missing an operator such as * p
+ //
+ lyxerr << "checking expr: '" << expr << "'" << endl;
+ string out = captureOutput("mint -i 1 -S -s -q -q", expr + ';');
+ if (out.empty())
+ break; // expression syntax is ok
+ istringstream is(out.c_str());
+ string line;
+ getline(is, line);
+ if (line.find("on line") != 0)
+ break; // error message not identified
+ getline(is, line);
+ string::size_type pos = line.find('^');
+ if (pos == string::npos || pos < 15)
+ break; // caret position not found
+ pos -= 15; // skip the "on line ..." part
+ if (expr[pos] == '*' || (pos > 0 && expr[pos - 1] == '*'))
+ break; // two '*' in a row are definitely bad
+ expr.insert(pos, 1, '*');
+ }
+
+ string full = "latex(" + extra + '(' + expr + "));";
+ string out = captureOutput("maple -q", header + full + trailer);
+
+ // change \_ into _
+
+ //
+ MathArray res;
+ mathed_parse_cell(res, out);
+ return res;
+ }
+
+
+ MathArray pipeThroughOctave(string const &, MathArray const & ar)
+ {
+ ostringstream os;
+ OctaveStream vs(os);
+ vs << ar;
+ string expr = os.str();
+ string out;
+
+ lyxerr << "pipe: ar: '" << ar << "'\n"
+ << "pipe: expr: '" << expr << "'" << endl;
+
+ for (int i = 0; i < 100; ++i) { // at most 100 attempts
+ //
+ // try to fix missing '*' the hard way
+ // parse error:
+ // >>> ([[1 2 3 ];[2 3 1 ];[3 1 2 ]])([[1 2 3 ];[2 3 1 ];[3 1 2 ]])
+ // ^
+ //
+ lyxerr << "checking expr: '" << expr << "'" << endl;
+ out = captureOutput("octave -q 2>&1", expr);
+ lyxerr << "checking out: '" << out << "'" << endl;
+
+ // leave loop if expression syntax is probably ok
+ if (out.find("parse error:") == string::npos)
+ break;
+
+ // search line with single caret
+ istringstream is(out.c_str());
+ string line;
+ while (is) {
+ getline(is, line);
+ lyxerr << "skipping line: '" << line << "'" << endl;
+ if (line.find(">>> ") != string::npos)
+ break;
+ }
+
+ // found line with error, next line is the one with caret
+ getline(is, line);
+ string::size_type pos = line.find('^');
+ lyxerr << "caret line: '" << line << "'" << endl;
+ lyxerr << "found caret at pos: '" << pos << "'" << endl;
+ if (pos == string::npos || pos < 4)
+ break; // caret position not found
+ pos -= 4; // skip the ">>> " part
+ if (expr[pos] == '*')
+ break; // two '*' in a row are definitely bad
+ expr.insert(pos, 1, '*');
+ }
+
+ if (out.size() < 6)
+ return MathArray();
+
+ // remove 'ans = '
+ out = out.substr(6);
+
+ // parse output as matrix or single number
+ MathAtom at(new MathArrayInset("array", out));
+ MathArrayInset const * mat = at->asArrayInset();
+ MathArray res;
+ if (mat->ncols() == 1 && mat->nrows() == 1)
+ res.append(mat->cell(0));
+ else {
+ res.push_back(MathAtom(new MathDelimInset("(", ")")));
+ res.back().nucleus()->cell(0).push_back(at);
+ }
+ return res;