Here's the first draft (documented in Pod 6, of course ;-).

Feedback and suggestions are most welcome.

(But please don't bother explaining to me this feature won't suffice
 as the high-level automatic code-to-documentation mechanism that Markov
 has been championing. I promise that I'm very well aware of that fact.
 This new formatting code isn't intended to replace such advanced
 autodocumentation tools...only to make such tools unnecessary in the
 simple cases and--in the non-simple cases--to make such tools easier to
 create, by providing a symbolic intermediate-level representation for
 interwoven code and Pod.)



=head3 Ambient aliases

The C<A<>> formatting code specifies an B<alias to an ambient antecedent>.
This is like a L<placement link|#Placement links>, except
that the text that is inserted to replace the C<A<>> formatting code is
some portion of the L<ambient section(s)|#General syntactic structure>
of the current document, rather than the entire contents of some
external document.

Hence, the C<A<>> code makes it possible to incorporate pieces of
ambient text (typically source code) into Pod documentation.
Specifically, the C<A<>> code is replaced by searching backwards through
all preceding non-Pod parts of the document, to locate the nearest prior
substring that matches the contents of the C<A<>> code.

The contents of an C<A<>> code can specify a back-reference of this type
in one of two ways:

=item  as a I<prefix keyword>, or

=item  as a I<delimited text range>.

By default, C<A<>> aliases are "keyword oriented". That is, the contents
of an C<A<>> block are treated as a keyword or prefix that introduces
the desired text. That text is located by searching backwards from the
location of the C<A<>> code, to find the nearest preceding instance of
the specified prefix in any previous ambient block. The text that is
then used to replace the C<A<>> is the first "symbol" following that
located prefix. In this context, a "symbol" is defined as a sequence of
non-whitespace characters terminated by a transition from an identifier
character to a non-identifier character.

For example, in the following:

=begin code
    class Pet {

        has $name;

    The class A<class> provides a A<has> attribute.
=end code

the C<A<class>> formatting code would be replaced by "Pet", since that
is the sequence of non-whitespace characters that immediately follows
"class" in the preceding ambient source code. Likewise, the C<A<has>>
formatting code would be replaced by "$name", because that is the
longest sequence of non-whitespace characters that follows a "has" and
terminates in an identifier-to-nonidentifier boundary.

=begin para
=config C<> :allow<R>
In other words, any formatting code of the form C<A<R<prefix>>>
is replaced by the substring of the nearest preceding
ambient block that matches the pattern:
=end para

=for code :allow<R>
    /  .*  R<prefix> \s*  <( \S*? \w )>  [\W | $] /

This default is designed to work well for the commonest kind of
back-reference in ambient text: a reference to a code construct that
was defined using a prefix keyword and whose name ends in an identifier.

The second and more general way of specifying an alias is to specify
both a prefix and a postfix delimiter for the replacement text. If the
contents of an C<A<>> formatting code include a range marker (C<..>),
the sequence before the C<..> is treated as the left delimiter of the
replacement text, and the sequence after the C<..> is the right
delimiter. In this case, there are no other constraints on the
replacement text. In particular, it may contain any number of non-
identifier or whitespace characters. For example:

    class Pet {

        method eat(Food $meal) {...}

    The A<method>() method has the following argument list: A<(..)>

This would be interpreted as:

    The eat() method has the following argument list: Food $meal

because the C<A<(..)>> specifies an alias to the closest preceding ambient
text that is left-delimited by a '(' and right-delimited by a ')'.

To specify an alias in which the sequence C<..> is itself
a left- or right-delimiter (rather than the separator between the two),
use a C<V<>> code:

    constant @range = 0..99;

    The maximum value is A<V<..>..;>

=head4 Explicit aliasing

The replacement strings for C<A<>> formatting codes are normally
specified implicitly, by the closest preceding ambient text that matches
the contents of the C<A<>> code.

However, it is possible to override this behaviour and create an
I<explicitly defined> alias, using the C<=alias> directive:

    class Agent {...}
    =alias component Agent

    class Transaction is Activity {

    The A<class> class represents a transaction activity between two
    A<component> objects.

In the preceding example, C<A<class>> is a normal "keyword" alias
(which would be replaced by the closest preceding prefixed match:
"Transaction"). However, C<A<component>> is a defined alias
(which would be replaced by the explicitly specified text: "Agent").

Each back-reference name defined by an <=alias> directive is lexically
scoped within the block structure of the surrounding Pod. To create
"global" aliases, define them at the start of the Pod document, at the
outermost block level.

Explicitly defined aliases always override normal prefix or delimited
aliases, and thereby allow you to refer to ambient constructs that would
otherwise be inaccessible to an implicit back-reference.

For example, within the C<DESCRIPTION> block of the previous example,
the Agent class couldn't be referred to as C<A<class>>, since the
intervening Transaction class "hides" it from the look-behind matching
of implicit back-reference mechanism. But the C<=alias> command allows
the name of the earlier class to be associated with a distinct symbolic
alias (i.e. "component"), which then allows it to be referred to
unambiguously, regardless of other intervening code.

Another way of thinking of this is that explicitly defined aliases
change the normal C<A<>> substitution behaviour from being determined
I<relatively> by the location of the C<A<>> code, to being determined
I<absolutely> by the alias name itself.

An C<=alias> directive expects two arguments:

=item The name of the new alias

=item The text with which that new alias is to be replaced

The alias name may be any sequence of non-whitespace characters. The
remainder of the line (ignoring the whitespace immediately after the
name) is treated as the replacement text. For example:

    =alias Smith  Jones
    =alias G&T    green tea
    =alias [EMAIL PROTECTED]  Gosh darn

    A<[EMAIL PROTECTED]> it, A<Smith>, you spilled my A<G&T>!

is equivalent to:

    Gosh darn it, Jones, you spilled my green tea!

To specify an alias name that includes a whitespace, or a replacement
text with surrounding whitespace, use a C<V<>> formatting code:

    =alias slow            V< >...slow
    =alias V<extra slow>   s-l-o-w
    =alias V<ultra slow>   V<  >s  l  o  wV<  >

    The service was not merely A<slow>, or even A<extra slow>.
    It was A<ultra slow>

Although only the C<V<>> code is significant within the name of an alias,
you can use I<any> formatting code(s) within the replacement text:

    =alias V<ultra slow>   S<  s  l  o  w  >
    =alias V<hyper slow>   B<...s...l...o...w...>

In particular, you can use an C<A<>> code in the replacement text of an
C<=alias>. This is useful to preserve the abstract relationship between
ambient code and Pod documentation. For example, in the earlier Agent
example, instead of:

    class Agent {...}
    =alias component Agent

the alias could have been defined:

    class Agent {...}
    =alias component A<class>

so that the class name did not have to be repeated as part of the alias.
This approach has the important benefit that the alias would not have
to be modified in any way if the name of the Agent class were
subsequently changed:

    class Operative {...}
    =alias component A<class>

Likewise, in the earlier range example, it would have been cleaner and
more maintainable to write:

    constant @range = 0..99;
    =alias max  A<V<..>..;>

    The maximum value is A<max>

Explicit aliases also provide a way to "retarget" implicit back-references
if they are later invalidated by keyword changes in the
source code. For example, given the following documented code:

=begin code
    class Transaction {

        my Int $trans_counter;

    The A<my Int> variable is used to track the total number of
    transactions active at any one time. The value of A<my Int> is
    incremented by A<class>'s C<BUILD> submethod and decremented by
    the A<class> destructor.
=end code

If a subsequent redesign requires that the class be changed to a role,
and the lexical counter converted to a state variable, then every
corresponding C<A<>> code in the documentation would have to be
altered too:

=begin code
    role Transaction {

        state Int $trans_counter;

    The A<state Int> variable is used to track the total number of
    transactions active at any one time. The value of A<state Int> is
    incremented by A<role>'s C<BUILD> submethod and decremented by
    the A<role> destructor.
=end code

A less onerous and error-prone solution would be to leave the original
C<A<>> codes "as is", and insert aliases to override the default prefix

=begin code
    role Transaction {
    =alias class  A<role>

        state Int $trans_counter;
    =alias V<my Int>  A<state Int>

    The A<my Int> variable is used to track the total number of transactions
    active at any one time. The value of A<my Int> is incremented by the
    A<class> C<BUILD> submethod and decremented by the A<class> destructor.
=end code

Note that C<=alias> is a fundamental Perldoc directive, like C<=begin>
or C<=for>; it is I<not> an instance of an
L<abbreviated block|#Abbreviated blocks>. Hence there is no paragraph
or delimited form of the C<=encoding> directive (just as there is no
paragraph or delimited form of C<=begin>).

Reply via email to