Juggle Home - Bits'n'Pieces - Feature Hitlist - Problem Reports - Mailing lists - The J Repository - References +-------------------+ | 9!:12'' | |5 | +-------------------+

Getting help in a J session using the Unix/Netscape Remote Control Feature

Abstract

Together with the J4.05/Unix distribution, Jsoftware released the online documentation in HTML format. This was a great improvement for J/Unix users. Even though the documentation itself is well modularized and offers many targeted entry points, J Release 4.05 only provides a poor 'jhelp' verb simply launching a HTML browser with the main page of the J online documentation. Moreover, using jhelp in conjunction with the Netscape Navigator might cause trouble on a Unix platform under certain circumstances.

This article deals with two topics: First, it introduces how the Remote Control Feature of Unix Netscape can be used to control Netscape from another process. Second, it describes how a more comfortable "help system" can be created. Although written to work on Unix platforms, the help system can be adopted to Windows with little porting effort.

Remote Controlling Unix Netscape

When Netscape is launched on a Unix platform it will recognize if another Netscape process is already connected to the same X display. If so, the new Netscape process will display a dialog reporting that it has detected a lock file which may indicate that another user is running Netscape. You may confirm the dialog and run another Netscape process, but you won't be able to use Netscape's cache, nor global history, nor - most seriously - personal certificates. Even if one accepts to run Netscape with these restrictions, this additional confirmation dialog is annoying.

The Unix version of Netscape provides a remote control feature which can be used to control a running Netscape process externally. From my experience, this useful feature is fairly unknown, maybe because its documentation is a bit hidden. The following snippet is taken from Netscape's application defaults file (Netscape.ad):

  ! You can control a running Netscape process externally; you do this by
  ! issuing a command like "netscape -remote openURL(http://xxx)".
  ! When Netscape is invoked with the -remote argument, it does not open
  ! window, but instead connects to and controls an already-existing process.
  ! This is done using X properties, so the two Netscape processes need not
  ! be running on the same machine, and need not share a file system.
  ! [...]
  ! Please see the document http://home.netscape.com/newsref/std/x-remote.html
  ! for more information.

Assuming that there is an X server running on the display in front of you, and that a Netscape process is connected to that X server, the following command entered in a Unix shell should display the documentation of Netscape's remote control feature.

 % netscape -remote "openURL(http://home.netscape.com/newsref/std/x-remote.html)"

If called this way, Netscape will reuse one of its already existent navigator windows and replace the contents with those of the new URL. To open the URL in a new window, pass the argument 'new-window' along with the URL to the netscape command, e.g.

 % netscape -remote "openURL(http://juggle.gaertner.de/,new-window)"

For the remote control feature Netscape uses X properties to tell another Netscape process what to do. Thus, you can send a remote control command to any Netscape process reachable in the network, where reachable means, the machine where the netscape remote command is invoked on has permissions to connect to the X server where the Netscape process to be controlled is connected to.

For example, if you want to show a colleague the Juggle homepage the following command will open the URL on his X display (assuming the X display's name is "foo:0", access to the X server is granted, and there is a Netscape connected to display "foo:0"):

 % netscape -display foo:0 -remote "openURL(http://juggle.gaertner.de/,new-window)"

Controlling Netscape from within J

Controlling Netscape from within J is straight forward. Using the foreign conjunction 2!:1, you can launch any Unix command. Thus,

   2!:1 'netscape -remote "openURL(http://www.jsoftware.com/,new-window)" 2>/dev/null'
will open a new navigator window displaying the Jsoftware home page.

If the netscape remote command fails (e.g. because there is no Netscape process connected to the X display), an error message will be reported to stderr and it will exit with a nonzero status. And if a command exits with a nonzero status the 2!:1 foreign will throw an interface error. (We will take advantage of this later.)

In a network environment Netscape and the J software might be installed on different hosts. Depending on whether Netscape is installed on the same machine as the jconsole or on a remote host, and depending on the value of the DISPLAY environment variable, one may define the stub of the command to invoke Netscape like one of the following:

   NETSCAPE =: 'netscape'
   NETSCAPE =: 'netscape -display bar:0'
   NETSCAPE =: 'rsh foo netscape -display bar:0'
   NETSCAPE =: 'rsh foo netscape -display ',2!:5'DISPLAY'
Note: If Netscape is invoked on a remote machine using rsh be sure that the remote host has permissions to connect to your X display.

Verify that the netscape command is defined correctly by trying, for example,

  2!:1 NETSCAPE,' -remote "openURL(http://juggle.gaertner.de/,new-window)"'

Putting all together, a verb 'netscape' may be defined as

   netscape =: verb define
     '' netscape y.
   :
     try.
       NB. Try the remote control feature
       2!:1 NETSCAPE,' ',x.,' -remote "openUrl(',y.,',new-window)" 2>/dev/null'
     catch.
       NB. Netscape is not runnig. Launch it.
       2!:1 NETSCAPE,' ',x.,' ',y.,'&'
     end.
   )

First, Netscape will be invoked using the -remote option. If the remote command fails (e.g. because there is no Netscape connected to the X display), the 2!:1 foreign throws an "interface error" and Netscape will be launched the "standard" way. To open the J online help page, try:

   netscape 'file:',(1!:42''),'system/extras/help/index.htm'

The dyadic case of the netscape verb can be used to pass additional options to the netscape command, e.g.

   '-display foo:0.0' netscape 'file:',(1!:42''),'system/extras/help/index.htm'

To view the command that will be launched in the netscape verb set the command stub to:

   NETSCAPE =: 'echo netscape'

Creating a J help system

The online documention of J is divided into files very well. There is a single HTML file for each J book, for each J primitive and so on. One can define an associative table to map a topic to the corresponding file, like:

   require 'misc'

   TOPICS =: chop ;._2 noun define
     dic system/extras/help/dictionary/contents.htm
     +   system/extras/help/dictionary/d100.htm
     +.  system/extras/help/dictionary/d101.htm
     +:  system/extras/help/dictionary/d102.htm
   )

The only thing missing to complete the Netscape based J help system is a verb which selects the help file for a topic and opens it:

   nshelp =: verb define
     '' nshelp y.
   :
     idx =. ({."1 TOPICS) i. <,y.
     x. netscape JDIR_j_, > {: idx { TOPICS
   )

Passing a J book shortcut or a J primitive, you now can jump directly into the corresponding J help document. For example:

   nshelp 'dic'   NB. ... opens the J dictionary
   nshelp '+'     NB. ... shows the vocabulary entry for Conjugate/Plus

Moreover, the annoying Netscape warning dialog was elimated by using Netscape's remote control feature.

A J script which implements the Netscape based help system outlined above including a topic table for all J books and all J primitives can be downloaded here, or by running

   netscape 'ftp://ftp.gaertner.de/pub/j/netscape.ijs'

Due to the 2!:1 foreign its use is currently limited to Unix platforms, but it should be easy to port it to Windows with little effort.

Goodies

Making the help system loadable to J would allow writing of the following Unix shell script:

  #! /bin/sh
  jconsole <<EOF >/dev/null
    require 'netscape'
    nshelp each <;._2 '$@ '   NB. $@ will be replaced with command line args
  EOF

If named 'jhelp' one may now use a Unix command too to view the J online help on a single topic, respectively on several topics:

  % jhelp +
  % jhelp '*' %           # Note: Special shell chars must be quoted

An interesting variant of the jhelp shell script may be used as a "bookmark viewer/launcher". Redefining the associative table TOPICS with bookmark/URL pairs, a shortcut may be used to open an URL in a Netscape Navigator window.

  #! /bin/sh
  jconsole <<EOF >/dev/null
    require 'netscape'

    NB. ---------------------------
    NB. Add bookmark/URL pairs here
    NB. ---------------------------
    TOPICS_netscape_ =: chop ;._2 noun define
      jsoftware   http://www.jsoftware.com/
      juggle      http://juggle.gaertner.de/
    )

    nshelp each <;._2 '$@ '   NB. $@ will be replaced with command line args
  EOF

If named 'nsview', an example of its usage would be

  % nsview jsoftware

+-------------------+ | 9!:12'' | |5 | +-------------------+ Juggle Home - Bits'n'Pieces - Feature Hitlist - Problem Reports - Mailing lists - The J Repository - References