Perl Scripting in Arbortext APP
ArborX

Open the Documentation Legend

Summary

This chapter details the use of the Perl scripting language within Arbortext APP.

Contents

1 Introduction

2 Installation

3 Integration

3.1 Reentrancy

4 Implementation

4.1 Perl versions and modules

4.2 Perl Snippets (V9)

5 Types of Perl Script in 3B2

5.1 Document specific Scripts

5.2 External String Scripts

6 Running/Executing Perl Scripts

6.1 The trun macro

6.1.1 Passing Parameters

6.2 Running internal perl scripts

6.3 Running external perl scripts

6.4 Stopping a Perl Script

7 Developing a Script

7.1 Perl Script Components

7.1.1 Variables

8 Perl Communication with 3B2

8.1 Calling Arbortext APP functions from Perl scripts

8.1.1 The macro Perl function

8.1.2 The AUTOLOAD function

8.2 Calling Perl scripts from Arbortext APP scripts

8.2.1 The perl command

8.3 Stream Access from Perl code

8.3.1 Read

8.3.2 Write

8.3.3 The tie function

8.3.4 Resolving APP variables from Perl (V9)

8.4 File streams

8.4.1 STDIN STDOUT and STDERR

8.4.2 STDIN

8.4.3 STDOUT

8.4.4 STDERR

9 Debugging a Script

9.1 The Perl Script Information Toolbars

9.1.1 The Perl Bar

9.1.2 The Script Bar

9.2 Comments

9.2.1 Multiple Comment Lines

10 Nested Multiple and Chaining Scripts

11 Perl miniscripts

11.1 Running a Perl miniscript

12 Perl function variable

13 Exporting and converting Perl scripts

13.1 Exporting internal scripts to external scripts

13.2 Converting internal scripts to an external string

14 Perl Files supplied with 3B2

14.1 The perl3b2.3ad file

14.2 The perluser.3ad file

15 Testing and developing Perl outside 3B2

15.1 Advantages of external development

15.2 Disadvantages of external development

16 Testing and developing libraries or modules

17 Perl and Unicode

18 Script Examples

18.1 Script Example 1

18.2 Script Example 2 - directory listing append and output

18.3 Script Example 3 - Get Plain Text and Mark-up in XML

19 Further Information and References

19.1 Internet Resources

19.2 Books/Literature

20 Subject Index

Introduction

Combining Perl with Arbortext APP's existing scripting capabilities means that the possibilities for automated solutions are hugely increased.  This section describes Perl scripting features in Arbortext APP and provides practical examples of Perl scripts.

Please note that this document is not a comprehensive technical overview of Perl. Perl itself is well documented and there are many external resources for learning Perl.

This document assumes that the reader has some prior knowledge of Perl and Arbortext APP scripting mechanisms therefore the purpose is to provide a specific description of Perl in Arbortext APP.  This is not a tutorial for programming with Perl. It is assumed that the reader is familiar with Arbortext APP and it is recommended that you read the Arbortext APP Scripting section before reading the Perl Scripting chapter.

For more information about Arbortext APP scripts see 3B2 Scripting and Showstrings. For more information about Perl see the Further Information and References at the end of this chapter.

Installation

You must install Perl with Arbortext APP (post version 7) for Arbortext APP to function, no matter if you use perl scripting or not and prior to installing the Arbortext APP application. From version 9 onwards Perl is automaticaly installed.

To install Perl simply follow the install instructions from the installation menu on the Arbortext APP CD as described below:

4 Select the type of install you want - either full, minimal or custom.

or

8 Click 'Next'

10 The necessary Perl files will be installed to your machine.

If you maintain different versions of Arbortext APP prior to 7.63a then you must install the Perl supplied with that later version in a separate directory or the old Arbortext APP will cease to function.

Integration

Now that the advantages of Perl have been incorporated, you can:

— Call Arbortext APP macros from a Perl script.

— Call Perl from Arbortext APP macros and expressions.

There is also full access to the complete library of Perl modules and the additional modules made available.

3.1 

Reentrancy

Pre version 8 it was possible for Perl code to call back to Arbortext APP with macro() and for that code to call back to Perl, and so on without limit. This was found to cause problems with stream data being corrupted. The fix is to throw a Perl error if you attempt to call back to Arbortext APP from within a Perl eval or channel. The error message you would see is:

 Perl3B2::call3b2 : Cannot call Arbortext APP from evalNB.

But you are currently able to call back to Arbortext APP from within a mini script.

— [P] These are the wrappers around the XS routine Perl3B2::call3b2()
NB. the AUTOLOAD allows calls to ttagedit() to 'map' to macro('ttagedit'). See "perl3b2.3ad"

—  [Q] The Perl3B2::Handle package allows for Perl code to access Arbortext APP streams.

Implementation

The original Arbortext APP Perl implementation (described in Technical Note 0038) ran each Perl script in a separate thread, and communicated with Arbortext APP using variables. This implementation caused problems on multi-processor machines and so was changed.

The version 8+ implementation of Perl now runs a Perl script in the main Arbortext APP thread and directly runs Arbortext APP macros from the Perl interpreter.

For Version 7.51 only it is possible to run Perl scripts simultaneously. From Version 7.63 onwards it is not possible to run Perl scripts simultaneously.  As a result, any scripts written using the Threads Library will not work because Arbortext APP Perl 5.6.1 is not built to support the old threading model.

The changes are minimal and existing Arbortext APP Perl scripts will work in the same way as before, however there are some changes to be aware of. The first change is that Arbortext APP can only respond to the user when the Perl script calls back to run a macro or read from a stream.

If you write a Perl script that spends a long time processing some data without calling back to Arbortext APP, then the interface will not respond to the user. To allow user interaction while a script is running, a subroutine has been added that will allow Arbortext APP to check its event queues and process any macros issued by the user:

 yield3b2           Check for user input.

As Perl scripts are no longer run in separate threads, you can only have one script running at any one time. A Arbortext APP script can still call a Perl script, and visa versa, but only the top level script will ever be running at one time.

4.1 

Perl versions and modules

3B2 versions come with their own version of Perl supplied that should be installed prior to the Arbortext APP application, however you can use an alternative version of Perl if need to, such as ActiveState for example.

In your sargsw.3ad Arbortext APP system file, there are a number of arguments for 3B2. The most common one will be '-p:Printer' to denote what printer you use. To tell Arbortext APP to use a different version of perl, use '-R' and point to your perl dll. For example:

 -R:/perl584/bin/perl58.dll

One reason you might want to do this is to use a specific perl module of a Perl version, for example acessing databases could be done this way, and you could use Win32::ODBC to access your database.

4.2 

Perl Snippets (V9)

Perl snippets are a new way to speed up Perl prossesing in documents which make heavy use of snippets. It works by turning the 'perl snippet' into an anonymous subroutine, and caching it. Arbortext APP will then store a mapping between the snippet and the subroutine. Each time a snippet is to be run we check to see if we have already compiled it into a subroutine, if not we create it, but either way it will be run. The result of calling the subroutine is the same as just evaluating the perl snippet.

They are controled from the 'speed' tab of the document preferences diologue box tdpref, or by using the perl_mode keyword.

Snippets apply to the 'perl' function and the 'perl' macro e.g.:

 <?show ^[perl "the pid is $$"]> 1
 [perl ...........] 2

It DOES NOT apply to perl streams e.g.:

  1
 trun "my_perl_script.pl" 2

Snippets are intended to be transparent to the user; that is, whether the feature is on/off should not affect the results from calling into perl from APP. The feature is enabled on a per document basis. If no document is open, and a call into perl is made then the 'compiling' is not done. The cache is a global one and is cleared when any document is closed to prevent it growing without limit.

Types of Perl Script in 3B2

5.1 

Document specific Scripts

Perl scripts within Arbortext APP documents are simply text streams, and can be entered in the edit bar or stream editor in the same way as Arbortext APP scripts. An internal Perl script is a script set in a normal text stream within the document and appended with the .pl tag extension.  It is recommended that you always use this extension for Perl scripts because Arbortext APP will then know to use the Perl interpreter when the script is executed.

When entering or editing a script, remember that you must stick to the rules of Perl syntax, for example, do not forget to include semi-colons at the end of statements. You may prefer to to develop or edit your perl scripts in a recognised perl syntax supporting editor and tester. To create a perl script stream enter the following in the macro bar:

 ttagmk 'name_of_script.pl'

The extension .pl tells Arbortext APP to use the Perl interpreter when running this script.

By creating a script within your document, you will easily be able to develop and test the script. It also means that the file is portable because regardless of where the file is located, the script will always be inside your document. The drawback with this method is that only the file containing the script will be able to use it.

5.2 

External String Scripts

External String Perl scripts are simply Perl scripts set into an external strings file, using a defined set of user string numbers. These files are generally located in the Arbortext APP system directory and read into Arbortext APP on start-up.  Scripts located in strings can be used form any document, or even when no document is open.

For information see Converting internal Perl scripts to external strings and 3B2 Scripting

Running/Executing Perl Scripts

6.1 

The trun macro

The trun macro controls the running of scripts. It can be used to start and stop both types of script (stream and string), either manually by the user by being entered in the macro bar, or automatically from within a script, for instance, the following syntax would run the Perl script called "my_script":

 trun "my_script"

The above example runs as a Perl script if the script has the file extension .pl or as a Arbortext APP script otherwise. It is recommended that you always use the .pl extension for Perl scripts because Arbortext APP will then know to use the Perl interpreter when the script is executed. However, if the script does not have the .pl extension then you will have to indicate that it is a Perl script by placing a 'p' in front of the script name.  It is therefore possible to use the following syntax to always run a script as a Perl script:

 trun p"my_script"

6.1.1 

Passing Parameters

Perl scripts can be passed a single string parameter in the same way as Arbortext APP scripts. This will appear in the standard Perl @_ array as element 0 (access it from Perl with $_[0]). There is no limit to the size of this parameter.

For more information see Passing Parameters in the Arbortext APP Scripting Chapter.

Perl scripts are usually run in one of two ways described in the following sections.

6.2 

Running internal perl scripts

Use the trun command followed by the name of your script in double quotes, for example:

 trun "name of script"

6.3 

Running external perl scripts

To execute an external string file use the trun command followed by the string number of your script.  Prefix the string number of your script with a 'p' to indicate it is a Perl script, such as:

 trun p6666

6.4 

Stopping a Perl Script

To stop a Perl script, use the standard trun -1 or trun 0 macros.  However, this will only be effective the next time the script makes a service request from Arbortext APP. If you write a script which never makes such a request then you will not be able to stop it from Arbortext APP.

For more information see 3B2 Scripting

Developing a Script

7.1 

Perl Script Components

7.1.1 

Variables

Version specific information6.77a  In terms of variable usage in Arbortext APP and Perl it is important to note the following, particularly for backward compatibility with scripts written prior to version 6.77a.

7.1.1.1 

Shared variables

Arbortext APP and Perl share the same variables. The implementation of variables in Perl is more comprehensive than that of Arbortext APP; therefore the Perl interpreter is responsible for all named variables.

That is, 3B2's variable ^varname is the same as Perl's $varname. Changes to one are reflected in the other.

7.1.1.2 

Case Sensitivity

All variable names are case sensitive. This means that previous Arbortext APP scripts that refer to ^variables with inconsistent case will not work.  Use the following search and replace to find all references to ^variables in any text stream and optionally replace them with lowercase names:

 /(\^[A-Za-z_]*[A-Z][A-Za-z_]*)/\\L\\1/craq

This will not catch any variables without the ^ prefix, such as with the getvar macro: getvar 00000 'variable'. This means that you will have to write another search and replace for that. Alternatively, write a stand-alone Perl script to scan entire Arbortext APP documents for inconsistent variable usage.

7.1.1.3 

Arrays

— Negative array indices now work backwards from the end of an array, with -1 being the last element. Previously, negative numbers were allowed as part of the 2000 range.

— There is no longer any limit to the number of characters stored in a variable or array element. Prior to Perl implementation in Arbortext APP version 7, the limit was 160.

7.1.1.4 

Lexical and Global Variables

All variables defined or called in a script are global variables which are stored as Perl package variables. Global variables exist during the whole Arbortext APP session.

Lexical variables are only available during the runtime of a Perl script.  They cannot be accessed from a Arbortext APP script.  It is possible to define variables and arrays as lexical using the Perl 'my' keyword.

You can define a global variable with the same name as a lexical variable.  The global variable will not be influenced by manipulating or defining a lexical variable with the same name.

7.1.1.5 

Accessing Perl Variables

Normal Variables

Perl splits its variables into three different types: package variables, lexical variables and special variables.  Lexical variables are declared using 'my';. Special variables are those like @ARGV and %SIG (see Special variables generated through startup of Perl) which mean something special to Perl.  Otherwise it is a package variable, for example:

Syntax

Type of Variable

my $x= 'a';

Lexical

$y = 'b';

Package

$SIG{'INT'} = sub {};

Special - global over all packages.

To access normal Perl variables or array elements (package variables) from Arbortext APP, simply use the existing syntax. The following are examples of using Perl variables with Arbortext APP syntax and next to each example is an explanation of the syntax:

Syntax

Explanation

@^text^

Inserts Perl's $text variable

^text=xyz

Sets Perl's $text variable

@^array(5)^

Inserts element 5 of Perl's @array variable

^array(5)=xyz

Sets element 5 of Perl's @array variable

Explicitly Named Package Variables

To access unusually named Perl variables such as those with fully qualified package names or the special punctuation variables, use the quoted name syntax, for example:

Syntax

Explanation

<show $^'Perl3B2::last_msg'^>

Accesses a fully qualified variable.

^error=^'@'

Accesses Perl's $@ variable

^'main::array'(^index)=23

This example only put quotes around the name, not any array index.

There is no direct access to Perl's other variable types, such as hash variables. These would have to be accessed via a script or miniscript.  However, it also possible to use the following syntax which approximates to direct access:
 ^[perl $hash{'whatever'}]

Perl Communication with 3B2

8.1 

Calling Arbortext APP functions from Perl scripts

8.1.1 

The macro Perl function

It is already possible to call macros from Arbortext APP scripts.  Any macro can also be called from a Perl script by using the 'macro' function, for example to call the refresh macro in a Perl script use the following syntax:

 macro 'trf';

The macro function takes a single string which is passed to the Arbortext APP processor for execution.  Therefore, when calling a Arbortext APP macro that refers to information in double quote delimiters, (like tf "times" for example) it is convenient to use the macro function with Perl's 'q' or 'qq' operators.  Use 'qq' to interpolate embedded variables or 'q' otherwise.

The example below calls the Arbortext APP insert (@) macro and inserts the text 'Insert this Text' at the current cursor position.

 macro q(@Insert this Text);

This example uses the Arbortext APP ttagmk command to create a new text stream called 'new'.

 macro q(ttagmk 'new.tx');

If the function involves using a variable, use the 'qq' function to interpolate embedded variables.  For instance this syntax makes a tag with the value of the variable called tagname:

 macro qq(ttagmk "$tagname");

8.1.2 

The AUTOLOAD function

Perl allows you to define a subroutine called AUTOLOAD which is called whenever it encounters a subroutine call for which it has not already seen a definition for. (Consult the Perl documentation for more details). Arbortext APP defines an AUTOLOAD subroutine which calls the macro of the same name as the 'missing' subroutine along with its arguments. Start by declaring which macros you will use during the script, using the syntax shown here:

 use subsqw(tcopy tpaste tformat trun);

When you have defined the macros you will use in a script with the AUTOLOAD function it is possible to call syntax directly without the need for the 'q' and 'qq' operators, for example:

 use subs 1
 qw(tformat ttagmk trun); 2
 tformat 1,10,'a'; 3
 ttagmk 'new.tx'; 4
 ttagmk $name; 5
 trun "conversion"; 6
1
Declares the commands and keywords to use in the Perl script.
2
Re-formats the document using the tformat command.
3
Makes a new text stream called 'new' using the ttagmk command.
4
Creates a variable called name.
5
Runs a script called 'conversion' using the trun command.
The AUTOLOAD function automatically adds double quotes around any non-number. This is not always what you want (for example, tformat ? or tpgoto +1). In these cases use Perl's 'q' or 'qq' operators as described above.

8.2 

Calling Perl scripts from Arbortext APP scripts

8.2.1 

The perl command

The perl macro enables Perl to be called directly, outside of any script context. The macro passes everything from the first non-space to the end of the macro line to the embedded Perl interpreter for evaluation.

Below are several examples of using the perl macro:

 ^var=22 5
 ^area={YE} 7
 ^j=0; 9

8.3 

Stream Access from Perl code

8.3.1 

Read

One method of gaining access to a stream would be to use a Arbortext APP variable assignment to handle this with the macro function:

 macro q(^variable=^'stream');

8.3.2 

Write

It is also possible to write to a stream using the variable assignment method used in Arbortext APP, for example:

 macro q(^'stream'=^variable);

8.3.3 

The tie function

Another way to access Arbortext APP text streams is provided via Perl's tied file handles. The Perl function tie binds a variable to a package which then implements various special subroutines.  In order to write the content of a text stream or reference in a Perl variable or to write the content of a Perl variable in a Arbortext APP element, a suitable implementation has been provided via the 'Perl3B2::Handle' package.

For example, to write the content of '$var' to the text stream 'txt1' use the following syntax.  It is described afterwards line by line:

 tie *TXT, 'Perl3B2::Handle' 1
 open TXT, '>txt1' or die; 2
 print TXT $var; 3
 close TXT; 4
6
Define a file handle 'TXT' using the 'Perl3B2::Handle' package.  (Replace 'TXT' with the name of your choice).
8
Open 'TXT' and associate it with a text stream 'txt1'.  It will be created if it does not exist.  In this case > stands for overwrite and >> stands for append.  If 'TXT' can not be opened the script will stop (die) with an error message.
10
The next step is to write the contents of $var to TXT.
12
Close the TXT file handle that you have opened.
Make sure you close the file handles you open.  If you do not close the file handles you have opened Arbortext APP will behave unpredictably.  This is particularly true if you close a document that has open handles pointing to any of its streams.

The method above writes the content of txt1 line by line.  If the content of txt1 has multiple lines it is possible to read or write the content line by line using a Perl while loop.  For example, this next example reads the content line by line:

 tie *ABC,'Perl3B2::Handle'; 1
 open ABC '<stream'; 2
 while (<ABC>) { 3
 $variable .= $_; 4
 }close ABC; 5
1
Define a file handle 'ABC' using the 'Perl3B2::Handle' package.  (Replace 'ABC' with the name of your choice).
2
Open the file handle 'ABC' and read the contents of txt1.
3-5
If the content of txt1 has multiple lines you can read it line by line using a while loop and adding each line to $var.
6
Close the 'ABC' file handle.

Alternatively, it is also possible to read the content in one single step using the following method:

 tie *IN,'Perl3B2::Handle','<stream'; 1
 seek IN,0,2; 2
 $len=tell; 3
 seek IN,0,0; 4
 read IN,$variable,$len; 5
 close IN; 6
1
Define a file handle 'IN' using the 'Perl3B2::Handle' package.  Open the Arbortext APP stream called 'stream' and tie to the filehandle IN.
2
The Perl seek function enables you to specify where the script reads the contents of the stream from.  'seek IN, 0,2;' moves the file pointer to the end of the file.
3
The Perl 'tell' function returns the current position of the last read file handle.
4
'seek IN,0,0;' moves IN's current position back to the start of the file.
5
Read $len number of characters from IN (starting at current position) and copy the contents into a variable.
6
Close the 'IN' file handle.

The example below demonstrates writing the result of a diamond operator in a stream:

 tie *OUT,'Perl3B2::Handle'; 1
 open '>stream';while (<IN>) { 2
 print OUT uc $_; 3
 } 4
 close OUT; 5
An Advent built Perl module is available called Advent3B2::TagHash which facilitates easy access to Arbortext APP tags from perl scripts. Please see the downloadable file and accompanying notes located at support.3b2.com - downloads - add-ons.

8.3.4 

Resolving APP variables from Perl (V9)

Version specific information8.13h  From the version 9 release, to resolve Arbortext APP variables from Perl, you can use the Perl3B2 function 'var3b2'.

The only existing method for properly resolving Arbortext APP variables inside Perl functions pre version 8.13h, involved resolving the variables within Arbortext APP and passing them to Perl using the shared script variables.

The new "var3b2" Perl function, available automatically via Perl3B2, allows a Perl script or miniscript to retrieve or modify any valid Arbortext APP variable type including such items as function variables, strings and FISH.

Be careful to avoid resolving ^[perl ..] function variables from var3b2, this works in theory but may become unpredictable for complex cases. For example:

Example
 # read variable 1
 my $fish = var3b2('^[fish 3,some_fish]'); 2
 # write variable 3
 var3b2('^[string 350]','A new value for the string.'); 4
 # read/write 5
 my $old_value = var3b2('^[stream test]','New Value'); 6
Note: the var3b2 syntax will not work from a "perl" macro call, or via the "^[perl ..]" function variable.

8.4 

File streams

8.4.1 

STDIN STDOUT and STDERR

Three file streams have special properties in Perl:

— Standard file error (STDERR).

These file streams are described in the following sections.

8.4.2 

STDIN

STDIN (standard input) is the default source of input.  This is the file associated with a keyboard.  STDIN is where typed data appears when a Perl program is running.

8.4.3 

STDOUT

STDOUT (standard output) is the default destination for output.  In a stand-alone Perl script, sending data to the STDOUT or STDERR, file handles will cause it to appear in the console window.

As there are no console windows within Arbortext APP's embedded Perl, STDOUT and STDERR are redirected to the tied file handle package 'Perl3B2::StdHandle' by default.  The output goes to the actual cursor position in Arbortext APP by invoking Arbortext APP's @ @ macro to enter the text.

It is also possible to redirect STDOUT to any Arbortext APP stream for example:

 tie *STDOUT, 'Perl3B2::Handle','>stream1';print 'hello';# now prints to stream1
Note that the redirection is active during your whole Arbortext APP session. If the redirected STDOUT is no longer required it is recommended to reset to default, so that the STDOUT prints to the current cursor position, as shown below:
 tie *STDOUT, 'Perl3B2::StdHandle';print 'hello';# now prints to the current cursor position (default).

8.4.4 

STDERR

STDERR is used by convention as the error stream of nearly all external modules.  STDERR (standard error) is the default place to send warnings and errors.

The default of this stream also goes to the actual cursor position. To redirect it, use the same syntax as shown for STDOUT above.

To reset STDERR to default use:

 tie * STDERR,'Perl3B2::ErrHandle';
Note that STDERR is not the output of compiler messages.

Debugging a Script

Perl has excellent error reporting and comprehensive debugging facilities.

It is also worth noting that the Stream Editor has syntax highlighting for Perl.

For more information on the Stream Editor see Dialogue Boxes and ttagedit

9.1 

The Perl Script Information Toolbars

9.1.1 

The Perl Bar

Before you write any complex Perl scripts it is a good idea to enable the error reporting from Perl. The Perl script information toolbars display Perl script information including error reports.

To enable the Perl bar:

— Select perlbar under the drop down lists under the Name: field in the Toolbars dialogue box.

Alternatively, enable the perlbar using the toolbars macro as shown below:

 toolbars "perlbar",2

There are two boxes on this toolbar:

— The current script nesting level and the name of the most recent running script.

9.1.2 

The Script Bar

There is an additional Perl script information toolbar that displays more information about nested and running scripts.

To enable the Script bar:

— Select script_bar under the drop down lists under the Name: field in the Toolbars dialogue box.

Alternatively, enable the script_bar using the toolbars macro as shown below:

 toolbars "script_bar",4

There is more information displayed on this toolbar:

— The other boxes provide a view of the callstack of the top ten running scripts.

If you want to keep your new toolbars for subsequent Arbortext APP runs, remember to use the tprefs macro to save your preferences.
For more information on nesting scripts see Nested Scripts - Multiple Scripts/Chaining Scripts. For more information on toolbars and editing toolbars see toolbars and tooledit
Another way of checking the syntax of a Perl script is to save the script to a file and then run perl from the command line with the -c switch, for example:
 perl -c 'script.pl'

You can also disable APP debugging functions to speed up formatting using the perl_mode.

9.2 

Comments

It is recommended that you add comments to your scripts. Comments enable you to know what each piece of a script is doing.  Perl will ignore comments in a script and just process the Perl statements.

In Perl, comments are as shown below:

 #This is a comment

A # comment instructs Perl to ignore everything from the # up until the end of the line.

It is also possible to have a comment on the same line as other Perl statements, for example:

 tie *TXT, 'Perl3B2::Handle'; #Define a file handle 'TXT'
Perl ignores blank lines; therefore blank lines are also a useful way of separating segments of your script, making it easier to read.  Remember that too many comments in your work will have a negative effect, making your script harder to read and understand.  It is important to strike a balance in this respect.

9.2.1 

Multiple Comment Lines

It is is also posible to have multiple lines of comments. This provides embedded Perl documentation. Multiple lines of comments end with =cut, for example:

 =head1

10 

Nested Multiple and Chaining Scripts

Just as with normal Arbortext APP scripts it is also possible to run more than one Perl script.  As with Arbortext APP scripts, Perl scripts can be nested. This means that a Perl script can use the trun macro to start another Perl script or Arbortext APP script.

As Perl scripts can have their own named subroutines, you may find that only one Perl script per task is necessary. In other words, there will often be no need to call nested Perl scripts for any given task.

It was originally intended that nesting Perl scripts could be particularly useful because each such script will run in a different thread, effectively meaning that Perl scripts could run simultaneously. However, this is no longer possible and there are several changes described in the Implementation Details below:

For more information about Nested Scripts see the Scripting Chapter

11 

Perl miniscripts

Miniscripts are scripts you can refer to within an expression to enable string manipulation. They are run directly in paragraph styles or in a text stream.

By running a Perl miniscript a global variable with the same name as the miniscript is generated.  This contains the content of the return value of the miniscript.  The return value holds the last assigned value in the script if explicitly set. 

There are some important points to note about miniscripts, including several restrictions:

— No calling back into 3B2. This includes the use of Perl::3B2StdHandle to access 3B2 streams.

— A Perl miniscript must be created with extension .pl

11.1 

Running a Perl miniscript

You can call Perl miniscripts in the same way as normal Arbortext APP miniscripts.  Miniscripts are scripts you can refer to within tag paragraph styles or in a text stream. Miniscripts are not executed using the trun command, but are referenced from within your document tags with the following showstring syntax:

To execute a miniscript use the following function variable syntax:

 <?show $^[mini perlmini]>

or

 <?show "^result"$^[mini perlmini]>

12 

Perl function variable

In version 8 a new set of features called function variables was implemented, one of which was 'perl'. This enables execution of single lines of perl script within a showstring, making simple perl functions normaly run via mini script even easier. The syntax for function variables is show below:

 <?show $^[perl $myvar=~s/found/replace/g;]>
For more information on function variables see perl function variable and Technote 0080; Function Variables; 7.80a

13 

Exporting and converting Perl scripts

13.1 

Exporting internal scripts to external scripts

To export an internal Perl script, simply use the tsavetxt macro, for example:

 tsavetxt "perl_script_name" "output_file" 1

Or just cut and paste the text of your script into your own text file.

13.2 

Converting internal scripts to an external string

You can save internal Perl scripts as external string number scripts with the tsave macro, for example:

 tsave 'script_name.3t'

It is then possible to modify the fdt-header in an external text editor such as Notepad.

For more information on Converting internal scripts to external string file scripts see the Scripting chapter.

14 

Perl Files supplied with 3B2

14.1 

The perl3b2.3ad file

When Arbortext APP starts, it allocates a single Perl interpreter and uses the interpreter for all Perl operations. During this initial process, Arbortext APP's Perl start-up file, perl3b2.3ad, is executed.

It is this file that provides the 'Perl3B2::Handle' and 'Perl3B2::StdHandle' packages and communication to Arbortext APP via the designated variables in the 'Perl3B2' package. Other Perl initialisation is also performed in this file.

It is important to note that perl3b2.3ad will be overwritten if you upgrade Arbortext APP.

The perl3b2.3ad file provides you with the following functions. If not explicitly mentioned all functions are exported into the namespace main:

Version

Function

Version 7.00a

macro();

Version 7.63a

yield3b2;

Version 7.67a

pvar_read(); pvar_write(); pvar_seek(); pvar_open(); Perl3B2::ChannelIO::close_channel(); Perl3B2::ChannelIO::open_channel(); Perl3B2::ChannelIO::seek_channel(); Perl3B2::ChannelIO::uninstall_channel_type(); Perl3B2::ChannelIO::write_channel();

Version 7.71a

expr3b2();

14.2 

The perluser.3ad file

Version specific information7.67a  Since Arbortext APP version 7.67a the optional perluser.3ad file can be created in your Arbortext APP program directory. Anything Perl related can be stored into this file and 3B2 will not overwrite it.

The perluser.3ad file is loaded before Arbortext APP is fully initialised. This means that actions relating to Arbortext APP may not work or in extreme cases even crash Arbortext APP.

15 

Testing and developing Perl outside 3B2

This only makes sense if main parts of your program can be separated in a way they run independently of Arbortext APP.

— Debug and test the functions by running test.pl simply in DOS or in your Perl development environment.

15.1 

Advantages of external development

— Some users may find it easier to run and edit than in the Arbortext APP environment depending on the quality of your editor.

15.2 

Disadvantages of external development

— No Arbortext APP macros available.

16 

Testing and developing libraries or modules

You must develop and test a Perl library or module that communicates with Arbortext APP in Arbortext APP.  However, modules and libraries are linked only once during the runtime of Perl.  Therefore they are linked only once in your Arbortext APP session. This is very good for the performance, but it is annoying to restart Arbortext APP after each change in the module during the development.  One way of reloading a module each time is to use 'do' instead of 'require' and 'use'.

17 

Perl and Unicode

From version 5.6 Perl has full UTF-8 support.  Because Perl uses UTF-8 encoding and Arbortext APP uses UTF-16 encoding it is necessary for Arbortext APP to internally convert characters to UTF-8 to be manipulated in Perl.  Once the manipulation has been performed, characters are converted back to UTF-16.

This process means that Perl scripts take fractionaly longer to complete than in the Arbortext APP standard version.

For further references on Perl and Unicode see the Further Information and References at the end of this document.

18 

Script Examples

18.1 

Script Example 1

This simple script defines two variables and inserts the contents of the variables at the current cursor position.  After the script there is a line by line description:

 $firstname='first';$lastname='last';macro q(@^firstname^);macro q(#13);macro q(@^lastname^);
1
Defines the variable firstname as 'first'.
2
Defines the variable lastname as 'last'.
3
Calls the Arbortext APP @ (insert macro) macro function.   The @ (insert macro) inserts the contents of the firstname variable at the current cursor position.
4
Emulates the keyboard entry of a carriage return (#13) using the # # macro.
5
Calls the Arbortext APP insert macro using the macro function.   The @ (insert macro) inserts the contents of the lastname variable at the current cursor position.

As an alternative to using the macro 'q' function to call the Arbortext APP commands it is also possible to use Perl syntax to achieve the same result, for example, instead of using:

 macro q(@^firstname^);macro q(#13);macro q(@^lastname^);

it is possible to use:

 print '$firstname\n';print '$lastname';
1
Inserts the contents of the variable firstname at the current cursor position. The \n is converted to a carriage return.
2
Inserts the contents of the variable firstname at the current cursor position.

18.2 

Script Example 2 - directory listing append and output

This example opens a directory in the same way as opening a file using the 'Perl3B2::Handle' package.  The contents of the directory are then output to the text stream strm0 with a body tag appended to each line.

 opendir DIR, 'c:\\Advent\\3B2\\' or die 'can't opendir /Advent/3B2 --$!\n'; 1
 @files = grep!/^\.\.?$/ , readdir DIR; 2
 closedir DIR; 3
 tie*OUT,'Perl3B2::Handle'; 4
 open OUT,'>strm0'; 5
 foreach $f(@files) {<br/>print OUT'<body>'$f'\n'; 6
 } 7
 close OUT; 8
1
Open the directory c:\Advent\3B2\.  DIR specifies the name of the directory handle.  Check the return value of the opendir to make sure it succeeded. If it didn't the script will die with the message 'can't opendir /Advent/3B2'.
2
readdir DIR returns a list of all the contents of the directory handle DIR.  This also contains the current directory (called '.') and the parent directory (called '..').  Perl's grep function takes an expression and uses this to 'filter' out a list.  The grep function will return the filenames that do not match the pattern specified, i.e. it will return the list of files (except for '.' and '..'). Then, @files is used to contain this list (see number 6).
3
Close the DIR directory handle.
4
Associate/tie the OUT file handle to Perl::Handle
5
Attach the OUT filehandle to Arbortext APP's 'strm0' for writing
7
Send data to 'strm0' via the OUT file handle.
8
The end of the 'while' loop.
9
Close the 'OUT' file handle. The tie is now severed and the Arbortext APP stream exists independently.

18.3 

Script Example 3 - Get Plain Text and Mark-up in XML

The following script shows how to open a text stream using a file handle, then the contents of the text stream are changed and the alterations output to a text stream called 'output'.  After the script there is a line by line description of each component of the script.

In the following example the text stream strm0 contains a list of names defined as such:

Chris,Western,

Bob,Davies

The aim of the script is to mark-up the list of names above to the result of the one name detailed below for all.  You will notice that the names have been separated and are now surrounded by 'tags':

<Name><Firstname>John</Firstname><Surname>Williams</Surname></Name>

To automate this conversion process use the script detailed below:

 tie *TXT, 'Perl3B2::Handle'; 1
 tie *OUT, 'Perl3B2::Handle'; 2
 open TXT , '<strm0'; 3
 open OUT , '>output'; 4
 while( defined($line =<TXT>) ) { 5
 ($first,$second) = split /,/ ,$line; 6
 print OUT 7
 "<Name><Firstname>$first</Firstname><Surname>$second</Surname></Name>\n"; 8
 } 9
 close OUT; 10
 close TXT; 11

19 

Further Information and References

19.1 

Internet Resources

For further general and in-depth information about Perl, sources, mailing lists etc:

www.Perl.com

Comprehensive Perl Archive Network - collection of Perl software and documentation:

www.cpan.org

Perldoc.com - Searchable repository of official Perl documentation. Including CPAN modules.

www.perldoc.com

19.2 

Books/Literature

Programming Perl

Larry Wall

Published by O'Reilly

Learning Perl

Randal L. Schwartz, Tom Phoenix

Published by O'Reilly

Perl Cookbook

Tom Christiansen, Nathan Torkington

Published by O'Reilly

Object Oriented Perl

Damian Conway

Published by Manning Publications

20 

Subject Index

Subject index only applicable to the PDF version.

Document created on 17-Sep-2002, last reviewed on 03-Oct-2005 (revision 5)