# -*- cperl-*-

=pod

=head1 contrib.mac

contrib/contrib.mac - the file responsible for loading other macro files

=head2 DESCRIPTION

This file is included by default in tred.mac and serves as a wrapper
for other contributed macro package inclusions.

Besides it provides file_opened_hook and file_resumed_hook in the
package TredMacros. These hooks should not be overriden by other macro
packages. See below how to plug context-specific code in.

=cut

#include "<*/contrib.mac>"

package TredMacro;

=pod

=head1 Context Guessing

=head2 @TredMacro::AUTO_CONTEXT_GUESSING

This global variable can be used by contributed TrEd macro packages to
plug-in their custom context guessing functions.  The purpose of such
a function is to detect whether the current file is suitable for the
macro package and if so, to indicate the correct binding context.

The function must return name of the context to switch to or undef if
the current file does not suit.

The synopsis for a package named 'Foo' is as follows:

  #binding-context Foo
  package Foo;
  BEGIN { import TredMacro; }
  context_guessing {
    my ($hook)=@_;
    if (PML::SchemaName() eq 'foo-data') { # some test that the file suites the macro package
      if ($hook eq 'file_opened_hook') {
         # some open-specific code
      } elsif ($hook eq 'file_resumed_hook') {
         # some resume-specific code
      }
      return 'Foo'; # return name of the macro package (context) to use
    }
    return;
  };

=cut

# ------------------------------------
# try guessing proper initial context
# ------------------------------------

#ifdef TRED

use vars qw(@AUTO_CONTEXT_GUESSING);
use Carp;
sub context_guessing (&) {
  __context_guessing($_[0],0); # will push
}
sub priority_context_guessing (&) {
  __context_guessing($_[0],1); # will unshift
}
sub __context_guessing {
  my ($code,$priority)=@_;
  if (ref($code) eq 'CODE') {
    if ($priority) {
      unshift @TredMacro::AUTO_CONTEXT_GUESSING, $code;
    } else {
      push @TredMacro::AUTO_CONTEXT_GUESSING, $code;
    }
  } else {
    croak "Usage: context_guessing { .... };"
  }
}


sub guess_context_hook {
  my ($hook)=@_;
  my ($mode)= GetPatternsByPrefix('mode',STYLESHEET_FROM_FILE());
  return SwitchContext($mode) if defined $mode;
  return unless $grp->{FSFile};
  foreach my $sub (@TredMacro::AUTO_CONTEXT_GUESSING) {
    my $ret = &$sub;
    if (defined($ret)) {
      SwitchContext($ret);
      return $ret;
    }
  }

  # do not leave the current context unless it explicitly rejects the file
  my $context = CurrentContext();
  if (UNIVERSAL::can($context,'allow_switch_context_hook') and
      &{$context.'::allow_switch_context_hook'}() eq 'stop') {
    SwitchContext('TredMacro');
    SetCurrentStylesheet(STYLESHEET_FROM_FILE());
  }
  return;
}

#endif TRED
