    The EMACS library PL1LIB contains macros to help edit PL1
code.  Since PL1 indentation styles vary a lot, the PL1LIB macros are
structured into an extensible scheme that allows the user control
over the kinds of indenting done.

    Load these macros into an EMACS, by MM Load Library$PL1LIB$$.
Then MM PL1 Mode$$ will set things up for editing PL1 code, such as
setting comment delimiters, and putting the statement indenter into
TAB.  If you want to set things up differently, you can provide a
macro named Init PL1 Mode.

    The main macro is ^R Indent PL1 Statement.  This macro is the
"driver" which implements the indentation scheme, calling special
indentation subroutines to do the actual work of indenting, based on
the kind of previous statement, if the macro is called to indent a
new statement.  If called to indent a new line of an unfinished
statement the indentation subroutine is chosen based on the current
kind of statement. There are indentation subrs provided for different
kinds of PL1 statement types, and you can provide your own to taylor
indenting style.

    BEWARE! Pl1 mode is not as smart as you or I. (Well... half right
at least...)  Avoid using statment keywords that drive indenting as
variables at the beginning of a statement, e.g. don't do:

	DO = ...;

Don't even do:

	DO = END;

    Everyone should acquaint themselves with ^R Indent PL1 Statement
(do "M User Calls" or just "N" to read about it). After that, you can
read about various indentation subrs to handle common PL1 statements
that are provided in the basic PL1LIB library (by doing "M Finished"
or "M Unfinished" from here, or just "N" from Indent Stmt). Those
interested in writing their own indentation subrs can read through
other parts of this info file.

    To insert a full description of the PL1 commands, ^R macros, and
subrs you can do:
	MM Load Library$ABSTR$
	MM Abstract File$ $ $PL1LIB$
Also, to keep up with changes or make suggestions, you can put
yourself on the INFO-PL1-MODE mailing list on MC.

^R Indent PL1 Stmt:

    The statement indenter is the main macro in the PL1LIB library.
It indents a statement by an amount that depends on the previous
statement's type, and whether it was finished (i.e. had a semi-colon
at its end -- you can call ^R Indent PL1 Stmt to indent a part of a
statement that was started on a previous line). Any existing
indentation is removed before indenting.
    After determining the previous statement's type (e.g. DO or IF,
based on the first non-label, non-comment token found in the
statement), ^R Indent PL1 Stmt will make up a name of an indentation
subr to handle indenting statements that follow that type: & PL1
Indent After <TYPE>.  If the previous statement was unfinished, the
indentation subr name is of the form & PL1 Indent Unfin <TYPE>.  If
there is no such subr, a default is called: & PL1 Indent After Stmt,
or & Indent Unfin PL1 Stmt.  These subrs indent based on the type and
indentation of the previous statement.
    If an ARG is specified (e.g. ^U TAB), if there are tokens to the
left in the line, or if indentation is beyond the desired column
(e.g. TAB TAB), then ^R PL1 Indent Relative is called.

^R PL1 Indent Relative:

    Successive calls indent under successive words of last line.

^R Global Comment, and ^R End Global Comment:

    Call ^R for a large comment.  Comment column is set to 10 and
auto fill is turned on.  End comment returns from this ^R.  This
macro may someday put the resulting text in a comment-box.

^R Slurp PL1 to Char:

    A fix for auto-fill indenting over too far, this macro pulls
non-comment text from previous line (back to CHAR typed) and inserts
it at point, calling the statement indenter again so you can see if
things look better now.

^R Print Last PL1 Indenter:

    Prints name of indentation subroutine that was called by the
statement indenter -- i.e. this will tell you what kind of previous
statement the indenter thought it was working with. (IF, DO, ...)
This macro is useful if you're not sure just what happened w

Indent PL1 Region:

    Calls the statement indenter for each line from here to MARK.  I
suggest that you use this carefully, e.g. indenting small,
screen-sized regions.  To protect against horrible mistakes, the old
text is put on the kill stack, and point and MARK surround the new.

Some related EMACS ^R macros that you may find useful, ordered by how
useful I find them, are:

  ^R Indent for Comment
  ^R End Comment
  ^R Indent New Comment Line (both comments and non-comments)
  ^R Delete Horizontal Space
  ^R Indent Nested
  ^R Indent Under (TMACS library version combines this and nested)

  ^R Back to Indentation
  ^R Delete Indentation

  ^R Indent Rigidly

  ^R Up Indented Line
  ^R Down Indent Line

If you want more you can always MM Apropos$Indent$, or
MM Apropos$Comment$...

    This section documents the indentation subroutines called to
handle new statements, i.e. there is nothing between here and the
previous statement end (;) except labels and comments.  Such
indentation subrs have names of the form & PL1 Indent After <TYPE>.
The PL1LIB library provides indentation subrs for finished previous
statements of type:
	IF, ON, ELSE,		(the compound statement types)
	DO, BEGIN,		(block beginners)
	PROC, ENTRY
	END,			(block ender)
	and the default		(previous statement had no specific
				 subr for it)
    The default for random previous statements, & PL1 Indent After
Stmt, just indents the same amount as the previous statement.  (If
this is the first pl1 statement in the buffer, indentation is given
by the variable $1st Stmt Indentation$, which has default 10.)

    The compound statements IF, ELSE, and ON contain sub-statements, and
indenting after these depends on the last sub-statement: if this last
sub-statement is a DO or BEGIN, the next statement is indented past
the DO/BEGIN by a user-specified amount, in variable $COMP BLOCK
INDENTATION$. I.e., & PL1 Indent After Compound will indent the next line
to align with the DO or BEGIN, and then indent $COMP...$ more.  The
default for $...$ is 0, in which case some examples are:

	IF ... THEN IF ... THEN DO WHILE I>0;
				here
or
	IF ...
	THEN BEGIN;
	     here

    If there is no DO or BEGIN, indentation is kept the same:

	IF ... THEN CALL FOO;
	here
or
	IF ...
	THEN IF ... THEN CALL FOO;
	here

    For $COMP BLOCK Indentation$ = 5:

	IF ... THEN BEGIN;
			 here

    DO and BEGIN statements start blocks which are indented to align
with the first non-whitespace following the DO or BEGIN, e.g.

	DO WHILE I > 0;
	   here
 or
	BEGIN;
	     here
or
	DO  I = 1 TO 50;
	    here

    Indent a constant amount, specified by $1st Proc Stmt Indentation$.
If not exist, defaults to 10.

    END statements are the trickiest: they search back over
preceeding statements until a matching DO, BEGIN, or PROC is found.
The indentation for the statement following the END is the same as
that of the statement containing the matching DO/BEGIN/PROC.

    For example:

	DO WHILE TRUE;
	   A = B;
	   IF THIS THEN THAT;
	   END;
	here

or
	IF THIS THEN DO;
		     A = B;
		     DO WHILE FOO;
			B = C;
			END;
		     CALL GAGGLE(GEESE);
		     END;
	here

    The unfinished-IF indents the same amount as the IF, if the THEN
hasn't occurred yet.  If it has, calls the default unfin-indenter.

    The unfinished compound for ON and ELSE indents the same amount
as the last sub-statement so far.

    The default is fairly hairy and has several mutually exclusive cases:

Case 1: If there is an open paren, align with next non-whitespace.
Case 2: If $Unfin Stmt Indentation$ exists, indent that more than
	start of statement.
Case 3: If prev line contains start of stmt, aligns with 1st word
        after beginning of stmt token (note: tokens may be several
        words, e.g. var_name is one token, two words).
Case 4: Calls ^R PL1 Indent Relative if the above cases don't hold.

    There are several subroutines available for use by indentation
subroutines, to help move to tokens past labels and comments, move to
previous statement ends,  find the last sub-statement in a
compound (IF or ON) statement, etc.

    These subroutines generally take arguments telling where to start
their searches from, and/or an iteration count.  Subroutines that
find tokens return two values, surrounding the token.  Subroutines
finding ends of statements return a pointer to the semi-colon.

    For failed searches, generally either b or z is returned for values.

    For more info on these subrs,  you can abstract PL1LIB as
mentioned earlier, or while it is loaded, you can MM List
Subroutines$$ and MM Describe$$ whatever looks interesting.