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