Here's a first working shot at an external, programmatic mechanism for opening .mw worksheets/Documents as new tabs in an already running Maple Standard GUI session.
This involves a `sh` shell script, runnable in Unix/Linux/OSX/cygwin. Maybe someone could post a MS-Windows .bat batch file equivalent.
The basic idea is this: you have a GUI session open. But you want to be able to open other .mw files in that session without having to go through the GUI's File->Open menu every time (since that doesn't remember position, or stay open, etc). Also, you may not want an entirely new Maple GUI instance to be fired up with every workeheet you try to open by double-clicking .mw files on your desktop.
You should be able to configure your own operating system filemanager to associate the .mw filename extension with some action. Except instead of having .mw associated with the Maple Standard GUI they'd instead be associated with this new shell script. With such an association, you'd just have to double-click .mw file icons in your favourite OS file manager in order to have them get opened as new tabs in your already running Maple GUI. Of course, if there is no instance of the Maple GUI already running then the script is supposed to start one up to open the selected file.
There are three files involved here. One is a shell script, in plain text. Another is a Maple commandline plain text file, which gets called by the shell script. And another is a .mw worksheet containing a few lines of Maple code. I'll put all of their contents below.
The .mw contents are as follows. This needn't necessarily go in a .mw file. It might also go inside one's .mapleinit file. The last Maple command here will never return, so any other work done in this GUI session will have to be done in a new worksheet/Document (with a new kernel) using File/New (just once).
------- server code, name it any .mw filename you want -------
serverfcn := proc(sid)
local str;
str:=Sockets:-Read(sid);
print(parse(str));
NULL;
end proc:
Sockets:-Serve(2525,serverfcn);
Now comes the commandline maple code.
------- client code, save this in automw.mpl ---------
# automw.mpl
# This runs a single procedure with no arguments.
# That procedure gets a worksheet filename from the
# shell variable "fname".
# It then attempts to open a Socket on port 2525 and,
# if successful, sends a command to open the file
# as a worksheet.
# If unsuccessful, it issues a system call to open the
# file in an entirely new xmaple session.
proc()
local fn, str, sid, sopened;
fn:=getenv("fname");
try
sid := Sockets:-Open("localhost.localdomain",2525);
sopened := true;
catch:
end try:
if sopened=true then
Sockets:-Write(sid, cat( "INTERFACE_WORKSHEET(display,file=`",fn,"`)" ));
else
str := cat("maple12 -s -x ",fn);
system(str);
end if:
end proc();
And lastly comes the shell script.
------- shell script, name it automw -------
#!/bin/bash # This is the shell script which starts the worksheet # autoloader client (commandline maple file automw.mpl) # The variable fname is assigned the first arg of this # shell script. The commandline maple script can grab that. fname=$1 export fname maple12 -s -q automw.mpl &
To see it work, open a Maple GUI session and execute the .mw server code above (or open the .mw file to which you saved it). Don't worry that the prompt never returned after you axecute the Sockets:-Serve command. Then run the automw shell script with the name of some .mw file as its argument. If things are working then that .mw should open in a new tab in the already running GUI.
You can notice that the shell script assumes that `maple12` is in your PATH and is how you fire up Maple 12. It assumes that localhost.localdomain works for your machine. You may need to adjust these things.
Of course, you'll want to make the automw shell script executable, with `chmod u+x automw`.
If anyone has any directions on how to associate a script with a filename extension in their favourite OS filemanager, that might be useful here.
The experts may wonder why I did not run the Sockets:-Serve call inside a Maple Thread, so that control would be returned to the main parent thread and hence avoiding any need for opened a new worksheet following execution of the server code. I have not been able to get that to work. If it worked then the server code go nicely be placed entirely out of view in one's .mapleinit file.
As always, improvements, comments, and fixes are welcome.
acer
Comments
No success yet
I have tried these steps in Debian Etch, but I have not got the same result yet. The result of executing the script automw from the console is a new Standard GUI instance that opens with the .mw file inside. When I close this second Standard instance, the control does not return to the console, and it looks like this:
$ automw lp.mw
$
0
Initially I have observed also a delay of about two minutes before the new Standard GUI opened, as if the link through the socket to the running Standard GUI is not being opened and a timeout occurs. But I do not know yet where the problem could be (a firewall issue?).
localhost
You might check that localhost.localdomain is OK for you (it appears in the code). There is a short and simple example in the help-page for Sockets:-Serve. You could see whether you can get that example to work for you. The posted code really doesn't do much more than that simple example in setting up the pair, except that the message gets sent to the "server" rather than from it.
You've probably already checked and changed any path and name for your `maple12`, etc.
acer
host name
It was exactly that: I have changed the host name and domain, and forgot about it...
Now it works provided I give the full name of the .mw file as parameter (ie with its path). The code number that I get on the console is 63. Otherwise, even executing the script (in the path) from the same directory with automw.mpl and the.mw file, an error message occurs that this mw file could not be found (and code 41).
In all, this is very interesting. It opens for me a whole new area of posibilities. I guess that similar things could be done from a compiled executable using OpenMaple.
in MS-Windows
This works also for me under Windows using this .bat file in the path:
For me maple12 is really a bat file in the path with a bit different name, that opens cmaple.exe, like:
and I have changed in automw.mpl localhost.localdomain to just localhost, as this works for me OK both under Linux and Windows.
Then, I execute the bat file as:
Note, the path with forward bars.
thanks
Thanks for this.
In MS-Windows one can use its "Open with" after right-clicking on a file icon. That mechanism even has a memory of recent actions for suggestions, if I recall. So one needn't alter the default handling of the ".mw" filename extension in order to try these techniques.
acer
Open with
This mechanism has some limitations, if I understand it correctly. It seems that it can add the executables from the list in the registry entry:
but this is a list of .exe names (without path). And, the Standard GUI executable in the late versions of Maple are all "maplew.exe". So I have only one here [for historical reasons Maple 10.06] and I cannot add another using the Open With dialogue box browser, apparently because this name slot is already filled.
Open with
Could you not open a .mw with the automw batch file, utilizing the "Open with" facility? That was my hope. Of course, the first time it's tried the batch file would have to be located with a "browse". (I thought that Windows could use .exe, .com, and .bat to "open" files.)
I was hoping that, used once, the batch file would stay in the short list of suggested applications for the given .mw filename extension.
The intention is also that the (maple) script fire up a new GUI instance as a fallback (on socket communication failure).
acer
path problem
Not yet, but because it seems to make a mess with the path (I had to write the .mw file path with unix forward bars to make the method work).
The fallback works because I have modified the line in automw.mpl to:
str := cat("m12s ",fn);where m12s is the bat file (in the path) that I have to open the Standard GUI.
My comentary was more related with the issue that I cannot have more than one version of maplew.exe in this "Open with" list. Here it is Maple 10.
In fact, my "default" file manager in Windows is Total Commander, and I set buttons to execute applications on the selected files (I have buttons for the different versions of Maple GUIs). I have not setup one for automw.bat yet.
PS: More precisely, the mess with the path is illustrated by this example:
"J:\temp\maple\test\lp.mw"; "J: empmaple estlp.mw"Ie. what ?backslash states:
Which is an advice to human typers. But what about programs that "insist" in writing single backslashes?
limitation
In ?release, it is stated:
consequences?
And so what are the practical consequences of that, and is it relevant here?
practical consequences
It sounds to me, may be wrong, that the only posibility is that this process runs without returning control. If so, it may be not be suitable for running from the init file.
sure
That agrees with my experiences and what I'd written. But one can open fresh (blank, new kernel) Worksheets in the GUI even when the Serve call is made in an already open tab.
acer
relative path to full path
I modified the automw script to convert a relative path for the argument to a full path, that allows running automw from any directory. Is there a nicer way to do the conversion? The following seems quite the (bash) hack:
fname="`cd ${1%/*};pwd`/${1##*/}" export fname maple -s -q $HOME/bin/automw.mpl &auto-start the port server
Here's a slightly modified approach. It requires the same two files as before, however, when automw.mpl launches xmaple, it uses two -c options to assign serverfcn and then start the Socket server. The first time automw is run, it opens the desired worksheet and launches the port server. Subsequent calls open worksheets in new tabs.
#!/bin/bash #~/bin/automw # This is the shell script which starts the worksheet # autoloader client (commandline maple file automw.mpl) # The variable fname is assigned the full path of the # first arg of this shell script. # The commandline maple script can grab that. fname="$1" # convert fname to absolute path if [ ${fname:0:1} != "/" ]; then fname=`pwd`/$fname; fi export fname maple -s -q $HOME/bin/automw.mpl &# This runs a single procedure with no arguments. # That procedure gets a worksheet filename from the # shell variable "fname". # It then attempts to open a Socket on port 2525 and, # if successful, sends a command to open the file # as a worksheet. # If unsuccessful, it launches xmaple, opens the worksheet, # and starts the server so that subsequent calls to # automw open worksheets in tabs. module() local fn, str, sid, serverfcn; serverfcn := proc(sid) local str; str:=Sockets:-Read(sid); print(parse(str)); NULL; end proc; fn := getenv("fname"); try sid := Sockets:-Open("clifford",2525); Sockets:-Write(sid, sprintf("INTERFACE_WORKSHEET(display,file=\"%s\")",fn )); catch "cannot establish TCP connection": system(sprintf("maple -x " "-c'Sockets:-Serve(2525,%a);'" " %s &" , eval(serverfcn) , fn )); end try; end module:possibility
Since the Sockets:-Serve call will not return (and since that doesn't appear to function from within a Thread), maybe the script could also send a string to automatically open a blank worksheet (after starting up of the GUI to initialize the Serve call).
I'm not sure that it's that big a deal. It's only one instance of having to do File->Open manually per session, compared to the many instances that may be avoided (for some people). And without a switch/option it would always be only either a Worksheet or a Document. And there might be a need (?) for the script to pause, until the socket is ready. And the blank .mw template file would need to read-only, unless someone figures out some other INTERFACE_WORKSHEET call which opens a new empty worksheet.
acer
fooled
I see what you mean; I was fooled by the ability to edit the worksheet into thinking that it could communicate with the maple server. Too bad Threads doesn't work here...