=head1 NAME

Parse::Template - Processeur de templates contenant des expressions Perl (0.32)

=head1 SYNOPSIS

  use Parse::Template;

  my %template = 
    (
     'TOP' =>  q!Text before %%$self->eval('DATA')%% text after!,
     'DATA' => q!Insert data: ! .
               q!1. List: %%"@list$N"%%! .
               q!2. Hash: %%"$hash{'key_value'}$N"%%! .
               q!3. File content: %%print <FH>%%! .
               q!4. Sub: %%&SUB()$N%%!
    );
 
  my $tmplt = new Parse::Template (%template);
  open FH, "< foo";

  $tmplt->env('var' => '(value!)');
  $tmplt->env('list' => [1, 2, 10], 
              'N' => "\n",
              'FH' => \*FH,
              'SUB' => sub { "->content generated by a sub<-" },
              'hash' => { 'key_value' => q!It\'s an hash value! });
  print $tmplt->eval('TOP'), "\n";

=head1 DESCRIPTION

La classe C<Parse::Template> permet d'évaluer des expressions Perl
placées dans un texte.  Cette classe peut être utilisée comme
générateur de code, ou de documents appartenant à un format
documentaire quelconque (HTML, XML, RTF, etc.).

Le principe de la génération de texte à partir d'un template est
simple.  Un template est constitué d'un texte qui comporte des
expressions à évaluer en des endroits balisés. L'interprétation de ces
expressions génère des fragments de textes qui viennent se substituer
aux expressions.

L'évaluation a lieu dans un environnement dans lequel on peut, par
exemple, placer des structures de données qui serviront à générer les
parties à compléter.


             TEMPLATE
          Texte + Expression Perl
		|
		+-----> Evaluation ----> Texte (document ou programme)
		|	
	   Subs + Structures de données
            ENVIRONNEMENT

La classe C<Parse::Template> permet de décomposer un template en
parties.  Ces parties sont définies par un tableau associatif passé en
argument au constructeur de la classe :
C<Parse::Template->E<gt>C<new('someKey', '... text with expressions to
evaluate ...')>. Au sein d'une partie, l'inclusion d'une sous-partie
se fait au moyen d'une expression de la forme :

  $self->eval('SUB_PART_NAME')

C<$self> désigne l'instance de la classe C<Parse::Template>. 

Vous pouvez vous contenter de ne mentionner que le nom de la
partie. Dans ce cas une routine du nom de cette partie est générée
dynamiquement. Dans l'exemple du synopsis l'insertion de la partie
C<TOP> peut ainsi se réécrire comme suit :

  'TOP' => q!Text before %%DATA()%% text after!

C<DATA()> est placée entre C<%%> et est de fait traiter comme une
expression a évaluer. 

Les routines acceptent des arguments.  Un argument peut être par
exemple utilisé pour contrôler la profondeur des appels récursifs d'un
template :

  print Parse::Template->new(
	   'TOP' => q!%%$_[0] < 10 ? '[' . TOP($_[0] + 1) . ']' : ''%%!
	  )->eval('TOP', 0);


Dans une expression vous pouvez utiliser les variables C<$self> et
C<$part>. La première désigne l'instance template, la seconde le nom
de la partie dans laquelle se trouve l'expression.

La méthode C<env()> permet de construire l'environnement requis pour
l'évaluation d'un template. Chaque entrée à définir dans cet
environnement doit être spécifiée au moyen d'une clé du nom du symbole
à créer, associée à une référence dont le type est celui de l'entrée à
créer dans cette environnement (par exemple, une référence à un
tableau pour créer un tableau).  Un variable scalaire est définie en
associant le nom de la variable à sa valeur.  Une variable scalaire
contenant une référence est définie en écrivant
C<'var'=>E<gt>C<\$variable>, avec C<$variable> une variable à portée
lexicale qui contient la référence.

Chaque instance de C<Parse::Template> est définie dans une classe
spécifique, sous-classe de C<Parse::Template>. La sous-classe contient
l'environnement spécifique au template et hérite des méthodes de la
classe C<Parse::Template>.

En cas d'erreur de syntaxe dans l'évaluation d'une expression
C<Parse::Template> essaie d'indiquer la partie du template et
l'expression à incriminer.  Si la variable
C<$Parse::Template::CONFESS> contient une valeur VRAIE la pile des
évaluations est imprimée.

=head1 METHODES

=over 4

=item new HASH

Constructeur de la classe. C<HASH> est un tableau associatif qui
définit le texte du template.

Exemple.

	use Parse::Template;
	$t = new Parse::Template('key' => 'associated text');

=item env HASH

=item env SYMBOL

Permet de définir l'environnement spécifique à un template.

C<env(SYMBOL)> retourne la référence assocée au symbole ou C<undef> si
le symbole n'est pas défini. La référence retournée est du type
indiqué par le caractère (C<&, $, %, @, *>) qui préfixe le symbole.

Exemples.

  $tmplt->env('LIST' => [1, 2, 3])}   Définition d'une liste

  @{$tmplt->env('*LIST')}             Retourne la liste

  @{$tmplt->env('@LIST')}             Idem


=item eval PART_NAME

Evalue le partie du template désignée par C<PART_NAME>. Retourne la
chaîne de caractères résultant de cette évaluation.

=item getPart PART_NAME

Retourne la partie désignée du template.

=item ppregexp REGEXP

Pré-processe une expression régulière de manière à pouvoir l'insérer
dans un template où le délimiteur d'expression régulière est un "/",
ou un "!".

=item setPart PART_NAME => TEXT

C<setPart()> permet de définir une nouvelle entrée dans le hash qui
définit le contenu du template.

=back

=head1 EXEMPLES


La classe C<Parse::Template> permet de se livrer à toutes sortes de
facéties. En voici quelques illustrations.

Le premier exemple montre comment générer un document HTML en
exploitant une structure de données placée dans l'environnement
d'évaluation. Le template comporter deux partie C<DOC> et C<SECTION>.
La partie C<SECTION> est appelée au sein de la partie C<DOC> pour
générer autant de sections qu'il y a d'élément dans le tableau
C<section_content>.

	my %template = ('DOC' => <<'END_OF_DOC;', 'SECTION' => <<'END_OF_SECTION;');
	<html>
	<head></head>
	<body>
	%%
	my $content;
	for (my $i = 0; $i <= $#section_content; $i++) {
	  $content .= SECTION($i);
	} 
	$content;
	%%
	</body>
	</html>
	END_OF_DOC;
	%%
	$section_content[$_[0]]->{Content} =~ s/^/<p>/mg;
	join '', '<H1>', $section_content[$_[0]]->{Title}, '</H1>', $section_content[$_[0]]->{Content};
	%%
	END_OF_SECTION;
	
	my $tmplt = new Parse::Template (%template);
	
	$tmplt->env('section_content' => [
				 {
				  Title => 'First Section', 
				  Content => 'Nothing to write'
				 }, 
				 {
				  Title => 'Second section', 
				  Content => 'Nothing else to write'
				 }
				]
		   );
	
	print $tmplt->eval('DOC'), "\n";

Le second exemple montre comment générer un document HTML à partir
d'une notation fonctionnelle, c'est-à-dire obtenir le texte :

	<P><B>text in bold</B><I>text in italic</I></P>

à partir de 

	P(B("text in bold"), I("text in italic"))


L'expression Perl permettant de produire ce genre de structure est
très simple et se réduit à :
	
	join '', @_

Le contenu à évaluer est le même quel que soit la balise et peut donc
être placé dans une variable. Nous obtenons donc le template suivant :

	my $ELT_CONTENT = q!%%join '', @_%%!;
	my $HTML_T1 = new Parse::Template(
			    'DOC' => '%%P(B("text in bold"), I("text in italic"))%%',
			    'P' => qq!<P>$ELT_CONTENT</P>!,
			    'B' => qq!<B>$ELT_CONTENT</B>!,
			    'I' => qq!<I>$ELT_CONTENT</I>!,
			   );
	print $HTML_T1->eval('DOC'), "\n";

Nous pouvons aller plus loin en exploitant la variable C<$part> qui
est définie par défaut dans l'environnement d'évaluation du template :

	$ELT_CONTENT = q!%%"<$part>" . join('', @_) . "</$part>"%%!;
	$HTML_T2 = new Parse::Template(
			    'DOC' => '%%P(B("text in bold"), I("text in italic"))%%',
			    'P' => qq!$ELT_CONTENT!,
			    'B' => qq!$ELT_CONTENT!,
			    'I' => qq!$ELT_CONTENT!,
			   );
	print $HTML_T2->eval('DOC'), "\n";


Voyons une autre étape qui automatise la production des expressions :

	$DOC = q!P(B("text in bold"), I("text in italic"))!;

	$ELT_CONTENT = q!%%"<$part>" . join('', @_) . "</$part>"%%!;
	$HTML_T3 = new Parse::Template(
				  'DOC' => qq!%%$DOC%%!,
				  map { $_ => $ELT_CONTENT } qw(P B I)
				 );
	print $HTML_T3->eval('DOC'), "\n";


Moyennant une dernière transformation il est possible d'utiliser une
notation invocation de méthode pour procéder à la génération :

	$ELT_CONTENT = q!%%shift(@_); "<$part>" . join('', @_) . "</$part>"%%!;
	$HTML_T4 = new Parse::Template(
				  map { $_ => $ELT_CONTENT } qw(P B I)
				 );
	print $HTML_T4->P(
	                  $HTML_T4->B("text in bold"), 
		          $HTML_T4->I("text in italic")
                         ), "\n";

C<Parse::Template> a été initialement créée pour servir de générateur
de code à la classe C<Parse::Lex>. Vous trouverez d'autres exemples
d'utilisation dans les classes C<Parse::Lex>, C<Parse::CLex> et
C<Parse::Token>.

=head1 APROPOS DE LA VERSION EN COURS

Il s'agit d'un module expérimental. Je suis très intéressé par vos
remarques et suggestions.

=head1 BUG

Les instances ne sont pas détruites. Donc n'utilisez pas cette classe
pour créer un grand nombre d'instances.

=head1 AUTEUR

Philippe Verdret avec l'aide d'Ocrat pour la traduction de la
documentation en anglais.

=head1 COPYRIGHT

Copyright (c) 1995-1999 Philippe Verdret. All rights reserved.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut
