commit aa8c92754b1a33b12ee12d924e9035253a4cfe42
Author: Pavel Sanda <[email protected]>
Date:   Wed Apr 30 19:47:00 2025 +0200

    Backport b3585ea76 & 9665f6d39a.
---
 src/LyXAction.cpp         |  9 +++++++--
 src/mathed/MathExtern.cpp | 39 +++++++++++++++++++++++++++++----------
 status.24x                |  6 ++++++
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index c2dfbc5a52..58702bebd8 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -2812,9 +2812,14 @@ void LyXAction::init()
  * \li Syntax: math-extern <LANG> [<COMMAND>]
  * \li Params: <LANG>: octave|maxima|maple|mathematica|script \n
                        where "script" stands for the external script 
(normalized
-                       expression will be passed)
+                       expression will be passed)\n
+               <COMMAND>: Particular command can be entered here. The way it 
will
+                          be used is language specific. E.g. for maxima it will
+                          be rewritten to the form:\n
+                          simpsum:true;tex(<COMMAND>(MATHED_EXPRESSION))}}
  * \li Origin: Andre, 24 Apr 2001
- * \li Sample: math-extern maple simplify
+ * \li Sample: math-extern maple simplify \n
+               math-extern maxima factor
  * \endvar
  */
                { LFUN_MATH_EXTERN, "math-extern", Noop, Math },
diff --git a/src/mathed/MathExtern.cpp b/src/mathed/MathExtern.cpp
index 41bdc6dea7..9b572bc881 100644
--- a/src/mathed/MathExtern.cpp
+++ b/src/mathed/MathExtern.cpp
@@ -1105,7 +1105,7 @@ namespace {
                return npos;
        }
 
-       MathData pipeThroughMaxima(docstring const &, MathData const & ar)
+       MathData pipeThroughMaxima(docstring const &command, MathData const & 
ar)
        {
                odocstringstream os;
                MaximaStream ms(os);
@@ -1113,6 +1113,16 @@ namespace {
                docstring expr = os.str();
                docstring const header = from_ascii("simpsum:true;");
 
+               docstring comm_left = from_ascii("tex(");
+               docstring comm_right = from_ascii(");");
+               // "simpsum:true;tex(COMMAND(EXPR));" if command (e.g. 
"factor") is present
+               if (command != "noextra") {
+                       comm_left = comm_left + command + "(";
+                       comm_right = ")" + comm_right;
+               }
+               int preplen = comm_left.length();
+               int headlen = header.length();
+
                string out;
                for (int i = 0; i < 100; ++i) { // at most 100 attempts
                        // try to fix missing '*' the hard way
@@ -1123,8 +1133,8 @@ namespace {
                        // 2x;
                        //  ^
                        //
-                       lyxerr << "checking expr: '" << to_utf8(expr) << "'" << 
endl;
-                       docstring full = header + "tex(" + expr + ");";
+                       docstring full = header + comm_left + expr + comm_right;
+                       lyxerr << "checking input: '" << to_utf8(full) << "'" 
<< endl;
                        out = captureOutput("maxima", to_utf8(full));
 
                        // leave loop if expression syntax is probably ok
@@ -1144,10 +1154,10 @@ namespace {
                        getline(is, line);
                        getline(is, line);
                        size_t pos = line.find('^');
-                       lyxerr << "found caret at pos: '" << pos << "'" << endl;
+                       lyxerr << "found caret at pos: '" << pos + headlen << 
"'" << endl;
                        if (pos == npos || pos < 4)
                                break; // caret position not found
-                       pos -= 4; // skip the "tex(" part
+                       pos -= preplen; // skip the "tex(" part
                        if (expr[pos] == '*')
                                break; // two '*' in a row are definitely bad
                        expr.insert(pos, from_ascii("*"));
@@ -1277,7 +1287,7 @@ namespace {
        }
 
 
-       MathData pipeThroughOctave(docstring const &, MathData const & ar)
+       MathData pipeThroughOctave(docstring const &command, MathData const & 
ar)
        {
                odocstringstream os;
                OctaveStream vs(os);
@@ -1289,6 +1299,14 @@ namespace {
                lyxerr << "pipe: ar: '" << ar << "'\n"
                       << "pipe: expr: '" << expr << "'" << endl;
 
+               string comm_left;
+               string comm_right;
+               if (command != "noextra") {
+                       comm_left = to_utf8(command) + "(";
+                       comm_right = ")" + comm_right;
+               }
+               int preplen = comm_left.length();
+
                for (int i = 0; i < 100; ++i) { // at most 100 attempts
                        //
                        // try to fix missing '*' the hard way
@@ -1296,8 +1314,9 @@ namespace {
                        // >>> ([[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);
+                       string full = comm_left + expr + comm_right;
+                       lyxerr << "checking input: '" << full << "'" << endl;
+                       out = captureOutput("octave -q 2>&1", full);
                        lyxerr << "output: '" << out << "'" << endl;
 
                        // leave loop if expression syntax is probably ok
@@ -1317,11 +1336,11 @@ namespace {
                        // found line with error, next line is the one with 
caret
                        getline(is, line);
                        size_t pos = line.find('^');
-                       lyxerr << "caret line: '" << line << "'" << endl;
+                       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
+                       pos -= 4 + preplen; // skip the ">>> " part and command 
prefix
                        if (expr[pos] == '*')
                                break; // two '*' in a row are definitely bad
                        expr.insert(pos, 1, '*');
diff --git a/status.24x b/status.24x
index d557fc80a0..117ff569fe 100644
--- a/status.24x
+++ b/status.24x
@@ -121,6 +121,12 @@ What's new
 
 - Correctly check maxima output for syntax errors.
 
+- Extend cooperation with computer algebra systems (bug 13178).
+  Maxima and Octave can now properly prepend commands in front of
+  expressions, e.g. you can use math-extern maxima factor
+  for factoring the expression in mathed. See LyX Function Manual
+  for details of math-extern function.
+
 
 * INTERNALS
 
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to