Part of Nobumi Iyanaga's website. n-iyanag@ppp.bekkoame.or.jp. 6/29/98.

logo picture

MacPerl with Frontier and Nisus Writer

Untitled

Introduction

Perl is certainly one of the most powerful and flexible scripting languages for text processing. Its port on the Macintosh platform, MacPerl, is an indispensable tool for many purposes, such as grep search of texts, etc (if you have to deal with Japanese texts, it is better to use MacJPerl). MacPerl cannot use many system calls available on the UNIX systems (and probably on MS-DOS), but it can send and receive AppleEvent; this functionality provides the users with some very useful features.

I use MacPerl especially in combination with Frontier and Nisus Writer . For example, I can select a word in a Nisus document, send to MacPerl commands to do a grep search of that word in one or more specified files, and receive the result in Nisus Writer. I can write Perl scripts in Nisus and execute them with MacPerl, receive the result, all in Nisus...

At the center of these processes, there is Frontier. Frontier can play the role of control tower of all the Macintosh system. Here is how I connect Nisus Writer to Frontier, and Frontier to MacPerl.


Basic concepts

To control applications from Frontier, we must first make glue tables for them. It is not difficult. -- I made a glue table for MacPerl that you can download here. It contains all the Frontier and Perl scripts described below (in fact, they are somewhat more complicated than those described here...), and other scripts also. I wanted however to show how to make a glue table for an application, so that you can make it yourself if you wanted to....

  1. Launch Frontier and choose Commercial Developers in the Suites menu (which is a sub-menu of Main menu in Frontier 5.0). A new menu, named Glue will appear at the right hand of Custom menu. Choose Enter Your Appl's Name... (or type simply "Cmd + 1"), and at the dialog which appears, enter (for example) "MacPerl".

    In fact, you can enter here any name you want, except space, period, hyphen or other "prohibited characters" in Frontier Object Database [ODB] names (so, be careful to not enter here "Mac Perl" or "MacPerl 5.0", etc.)
    After that, there are several dialogs to which you must answer:

    1. "Create a new glue script table for MacPerl ?"
      -> "OK"
    2. "Create a new appInfo table for MacPerl ?"
      -> "OK"
    3. "Does MacPerl support Menu Sharing ?"
      -> "No"
    4. [A standard file open dialog, with the prompt:] "Where is MacPerl ?"
      -> You locate your copy of MacPerl.
    5. "Create glue scripts based on MacPerl's 'aete' resource ?" -> "OK"

    Frontier will be working for a while, and after that, all the process is finished. You have no more need of Glue menu; type "Cmd + -" (equivalent of Minimal Menus sub-menu-item in the menu-item Suites), and this menu will disappear.

    I think that when it has finished, the new glue table is opened in Frontier -- if it is not, you can open it anyway by searching it in the Object Database, in the "system.verbs.apps" table.

    To test if this glue table works, you can use for example the Quick Script window: open it ("CMD + ;"), and type there:

    with MacPerl {launch (); bringToFront ()}
    and run it (click on the "Run" button, or type "Enter" key).

    You can do the same test from Nisus. Type simply the same Frontier command in a Nisus document, select it, and choose Frontier Do Script sub-menu-item in Macros menu, while holding down the Shift key (the sub-menu-item Frontier Do Selection seems to be broken).

    MacPerl will launch, and will be at the front.

  2. Now, the newly created MacPerl glue table has many items in it, but the only important one for us is MacPerl.doScript () command.

    We have to create two new tables in the MacPerl table. Choose New Table twice in Table menu in Frontier, and type "scripts" for the first one, and "runScripts" for the other one.

    Open the table MacPerl.scripts, and create a new wpText object, choosing New Text in Table menu, naming this object for example "simplestGrep. Type the following Perl script in this new MacPerl.scripts.simplestGrep:

    #!usr/bin/perl
    

    @ARGV = 1#@#;

    $term = '2#@#';

    $ct = 0; $found = 0; if (length($term) > 1){ for $file (@ARGV){ open (FILE, $file) || die "Couldn't open the $file..."; if ($ct > 0) { print ($file, "\n\n"); } while(<FILE>){ if (/$term/) { $found++; print; } } if ($ct > 0) { print "\nFound $found occurences\n\n"; } $found = 0; $ct++; } } close (FILE);

    If you know Perl scripting, you should notice in this script some strange codes. Although I am a very bad Perl scripter, these strangeness are intended, and you will soon see the reasons.

    Now, save and close this wpText object; then open the table MacPerl.runScripts. Create a new script named, "runScript". This script will be something like the following:

    on runScript (scriptName, ARGList, ifBringToFront = false)
       local (perlScript = string (MacPerl.scripts [scriptName]), res)
       bundle << put arguments
          for i = 1 to sizeOf (ARGList)
             tempARG = ARGList [i]
             if typeOf (tempARG) == listType
                tempARG = MacPerl.utilities.frontierList2PerlList (tempARG)
             perlScript = string.replace (perlScript, i + "#@#", tempARG)
       with MacPerl
          if not isRunning ()
             launch ()
          if ifBringToFront == true
             bringToFront ()
          res = doScript (perlScript, mode:batch)
       return (res)
    
    You see how all this works. The script MacPerl.runScripts.runScript () grabs the script in MacPerl.scripts.simplestGrep and stores it in the variable "perlScript". Then the script will replace "1#\@#" with the file path or the file paths list given in the first element of the second parameter in list ARGList, and "2#\@#" with the second element of the same parameter ARGList. It will launch MacPerl -- bringint it to the front, if the third parameter, ifBringToFront, says so (MacPerl runs much faster when it is at the front, so the parameter ifBringToFront should be set to true, if the job to be done is very large), and send to MacPerl the command to execute the script.
    It is the line:
    res = doScript (perlScript, mode:batch)
    which is the core of all this script. If it says:
    res = doScript (perlScript)
    without the parameter mode:batch, the return value (res) will be simply "true", and the result of the Perl script will be displayed in MacPerl's STDOUT window; but with this parameter given, the result will be returned to "res".

    Here is the script MacPerl.utilities.frontierList2PerlList:

    on frontierList2PerlList (frontierList)
       local (res = string (frontierList))
       res = "(" + string.mid (res, 2, string.length (res) - 2) + ")"
       return (string.replaceAll (res, "\"", "'"))
    

    If you call this script like this, giving it a Frontier list:
    MacPerl.utilities.frontierList2PerlList ({"a", "b", "c", 1, 2, 3})
    it will return a Perl formatted list, like this:
    ('a', 'b', 'c', 1, 2, 3)

    Thus, callint MacPerl.runScripts.runScript in this way:
    runScript ("simplestGrep", {{"Macintosh HD:Desktop Folder:test.txt"}, "myKeyword"})
    will generate a MacPerl script like this:

    #!usr/bin/perl
    

    @ARGV = ('Macintosh HD:Desktop Folder:test.txt');

    $term = 'myKeyword';

    $ct = 0; $found = 0; if (length($term)> 1){ for $file (@ARGV){ open (FILE, $file) || die "Couldn't open the $file..."; if ($ct > 0) { print ($file, "\n\n"); } while(<FILE>){ if (/$term/) { $found++; print; } } if ($ct> 0) { print "\nFound $found occurences\n\n"; } $found = 0; $ct++; } } close (FILE);

    There are other ways to run Perl scripts from Frontier, but I think that this one is the most efficient way.

  3. Now, you can try to run this MacPerl script from Nisus Writer using "Frontier Do Script" command. The result will be returned in Nisus Writer's clipboard. So if you want to display the result in a new Nisus document, all you have to do is to open a new document and paste there the content of the clipboard.
    Open a new document in Nisus Writer, and type there this three lines macro:

    Frontier Do Script 'MacPerl.runScripts.runScript ("simplestGrep", {{"Macintosh HD:Nisus Writer 5.1 Folder:Release Documents:Macros Documentation"}, "file"})'
    New
    MacroPaste

    Select it and choose "Execute Selection" in Macros menu.


Run Perl scripts from Nisus Writer

Now that you know the basic elements as to how to run Perl scripts from Frontier (and also from Nisus Writer), I think you would like to do the same thing more simply from Nisus Writer -- it is indeed cumbersome to have to type always the file paths in Nisus documents, etc.

Here again, I wrote a Frontier glue table for Nisus Writer, and a set of Nisus macros Frontier Sample Macros to facilitate all the process (see Nisus/Frontier Kit); I wrote also another set of Nisus macros to demonstrate how to play with MacPerl scripts from within Nisus Writer (Nisus Perl Macros). You may want to download these files. But I would like to explain some of the basic ideas.

We can use Nisus Catalog window to automate the entering of file paths. If you select a file in the Catalog window, and execute the following macro, you can get the full path of that file in the clipboard:

MacroCopy
fname = Clipboard - NumToChar (13) // we must remove the return character
path = DocPath //path of the directory displayed in the Catalog Window
fpath = path + fname
Clipboard = fpath

To send it to Frontier, we have to enclose this path between double-quotes: So the whole process will be something like this:

MacroCopy // Copy the selected word
term = NumToChar (34) + Clipboard + NumToChar (34) //enclose it between double-quotes
// Activate the Catalog window
Show Catalog
MacroCopy // Copy the selected file name
fname = Clipboard - NumToChar (13) // remove the return character
path = DocPath
fpath = path + fname
fpath = NumToChar (34) + fpath + NumToChar (34)

//we prepare the Frontier script in the clipboard...:
scriptName = NumToChar (34) + "simplestGrep" + NumToChar (34)
clipboard = "MacPerl.runScripts.runScript (" + scriptName + "{{" + fpath + ",} " + term + "})"
Frontier Do Script 'CC'

//Paste the result in a new document
New
MacroPaste


Using Nisus Writer as MacPerl editor

Another little Frontier script, and a Nisus macro, will allow you to use Nisus Writer as a MacPerl script editor. We will be able to write MacPerl scripts in Nisus documents, and send them to be executed by MacPerl. The needed script and macro are even simpler than the scripts/macros described above.

Create a new script in the MacPerl.runScripts table, and name it "runEditorScript". Its content should be the following:

on runEditorScript (perlScript = "", ifBringToFront = false)
   local (res)
   if perlScript == ""
      perlScript = MacPerl.scripts.scriptTemp
   with MacPerl
      if not isRunning ()
         launch ()
      try
         res = doScript (perlScript, mode:batch)
      else
         scriptError (tryError)
      return (res)

As you see, the MacPerl script that is to be executed by MacPerl must be in the cell MacPerl.scripts.scriptTemp. Now, what we have to do is to send a selected text (which will be a MacPerl script) in a Nisus document to this cell. This is very simple. We will simply copy the selected text, and send it to the cell MacPerl.scripts.scriptTemp. Here is a Nisus macro that will do it:

MacroCopy
Frontier Do Script "MacPerl.scripts.scriptTemp = clipboard.getValue ('TEXT')" "-"

The last "-" is for not to receive the result of the Frontier script in Nisus' clipboard (here, a true).
Now, we have only to call this macro, execute the Frontier script MacPerl.runScripts.runEditorScript () and display the result in Nisus. Here is the Nisus macro which will do it:


MacroCopy
Frontier Do Script "MacPerl.scripts.scriptTemp = clipboard.getValue ('TEXT')" "-"
Frontier Do Script "MacPerl.runScripts.runEditorScript ()"
New
MacroPaste


Applications: Work with other editors...

I think that you already foresee the possibility of applying all these techniques with other scriptable editors or word-processors than Nisus Writer. As an example, I take here Jedit 2.0x, a very powerful Japanese scriptable text editor. I wrote a Glue table for Jedit 2.0x; and I made in it a table called Jedit.basicUtilities. I gathered there some scripts of general use, such as "getSelection ()" or "newDocumentWithStr (str)". Using these scripts, it is very easy to use Jedit as another MacPerl script editor. Here is the Frontier code for it:

I only have to call these scripts:

on MacPerlEditor ()
   local (perlScript = Jedit.basicUtilities.getSelection (), res)
   res = MacPerl.runScripts.runEditorScript (perlScript)
   jedit.basicUtilities.newDocumentWithStr (res)

Finally, to call this script from within Jedit, I will use either OASMenu or Mr.PC. Here is the one line script for it:

Jedit.specialUtilities.MacPerlEditor ()

You will find here a little Frontier script to make a Frontier shared menu for any application with OSA Menu.


Conclusion...

I hope that this little page will have shown you how it is easy to work with MacPerl and other scriptable text editors or word-processors, using Frontier as a "control tower".

Now, it is your turn to play with the new possibilities. Only things that you have to have are:

HAVE FUN!


Go to Research tools Home Page
Go to NI Home Page


Mail to Nobumi Iyanaga


frontierlogo picture

This page was last built with Frontier on a Macintosh on Mon, Jun 29, 1998 at 16:14:29. Thanks for checking it out! Nobumi Iyanaga