home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Tk / HTML / Handler.pm < prev    next >
Encoding:
Perl POD Document  |  1997-08-10  |  14.3 KB  |  779 lines

  1. package Tk::HTML::Handler;
  2. require HTML::Parse;
  3. require Tk::HTML::Form;
  4. require Tk::Table;
  5.  
  6. use Carp;
  7.  
  8. delete $HTML::Element::OVERLOAD{'""'};
  9.  
  10. sub HTML::Element::enclosing
  11. {
  12.  my $self = shift;
  13.  my $must = shift;
  14.  my $p = $self;
  15.  while (defined $p) 
  16.   {
  17.    my $ptag = $p->{'_tag'};
  18.    for (@_) 
  19.     {
  20.      return $p if $ptag eq $_;
  21.     }
  22.    $p = $p->{'_parent'};
  23.   }
  24.  Carp::croak $self->tag . " is not in ".join(' ',@_) if ($must);
  25.  return undef;
  26. }
  27.  
  28. my %FontTag = ('CITE' => 'I', 'STRONG' => 'B', 'EM' => 'B', 
  29.                       'TT' => 'KBD', 'SAMP' => 'CODE');
  30.  
  31. my $tag; 
  32. foreach $tag (qw(b i samp code kbd strong em var cite dfn tt))
  33.  {
  34.   *{"$tag"} = \&FontTag;
  35.  }
  36.  
  37. foreach $tag (qw(address html blink))
  38.  {
  39.   *{"$tag"} = \&DoesNothing;
  40.  }
  41.  
  42. foreach $tag (qw(dl ul menu dir ol))
  43.  {
  44.   *{"$tag"} = \&List;
  45.  }
  46.  
  47. foreach $tag (1..6)
  48.  {
  49.   *{"h$tag"} = \&Heading;
  50.  }
  51.  
  52. foreach $tag (qw(tagAdd insert))
  53.  {
  54.   *{"$tag"} = sub { shift->{widget}->$tag(@_) };
  55.  }
  56.  
  57.  
  58. *th   = \&td;
  59. *link = \&a;
  60.  
  61. sub AUTOLOAD
  62. {
  63.  my $what = $AUTOLOAD;
  64.  # print "AUTOLOAD:$what\n";
  65.  my($package,$method) = ($what =~ /^(.*)::([^:]*)$/);
  66.  warn "Don't know how to $method";
  67.  print STDERR "Don't know how to $method\n";
  68.  *{"$what"} = sub { return 1 };
  69.  goto &$what;
  70. }
  71.  
  72. use strict;
  73.  
  74. sub Widget { shift->{widget} }
  75.  
  76. sub DESTROY
  77. {
  78.  
  79. }
  80.  
  81. sub new
  82. {
  83.  my ($class,%args) = @_;
  84.  my $w = $args{widget};
  85.  $w->delete('0.0','end');
  86.  $args{NL}   = 2;
  87.  $args{BODY} = 1;
  88.  $args{Count} = 0;
  89.  $args{'List'} = [];
  90.  $args{'FORM'}   = []; # all forms defined for this document
  91.  $args{'Text'}   = []; # Current place to send Text
  92.  $args{'Option'} = []; # Current place to send Option
  93.  return bless \%args,$class;
  94. }
  95.  
  96. sub CurrentForm
  97. {
  98.  my ($w,$f) = @_;
  99.  if (@_ > 1)
  100.   {
  101.    $w->{'CurrentForm'} = $f;
  102.   }
  103.  return $w->{'CurrentForm'};
  104. }
  105.  
  106. sub GenTag
  107. {
  108.  my $w = shift;
  109.  my $prefix = shift;
  110.  my $tag = $prefix . ++$w->{Count};
  111.  $w->{'GenTag'} = [] unless (exists $w->{'GenTag'});
  112.  push(@{$w->{'GenTag'}},$tag);
  113.  $w->{widget}->tagConfigure($tag,@_) if (@_);
  114.  return $tag;
  115. }
  116.  
  117. sub TextHandler
  118. {
  119.  my $w = shift;
  120.  if (@_)
  121.   {
  122.    push(@{$w->{'Text'}},Tk::Callback->new(@_));
  123.   }
  124.  else
  125.   {
  126.    return (@{$w->{'Text'}}) ? $w->{'Text'}[-1] : undef;
  127.   }
  128. }
  129.  
  130. sub nl
  131. {
  132.  my ($w,$n) = @_;
  133.  while ($w->{'NL'} < $n)
  134.   {
  135.    $w->insert('insert',"\n");
  136.    $w->{'NL'}++;
  137.   }
  138. }
  139.  
  140. sub ElemTag
  141. {
  142.  my ($w,$elem) = @_;
  143.  my $tag = uc $elem->tag;
  144.  $w->tagAdd($tag,$elem->{'_Start_'},$elem->{'_End_'});
  145. }
  146.  
  147. sub FontTag
  148. {
  149.  my ($w,$f,$elem) = @_;
  150.  if (!$f)
  151.   {
  152.    my $tag = uc $elem->tag;
  153.    $tag = $FontTag{$tag} if (exists $FontTag{$tag});
  154.    $w->tagAdd($tag,$elem->{'_Start_'},$elem->{'_End_'});
  155.   }
  156.  return $f;
  157. }
  158.  
  159. sub body
  160. {
  161.  my ($w,$f,$elem) = @_;
  162.  $w->{'BODY'} = 1;
  163.  return $w;
  164. }
  165.  
  166. sub script
  167. {
  168.  my ($w,$f,$elem) = @_;
  169.  $w->{'BODY'} = 0;
  170.  return $w;
  171. }
  172.  
  173. sub bgsound
  174. {
  175.  my ($w,$f,$elem) = @_;
  176.  return 0;
  177. }
  178.  
  179. sub head
  180. {
  181.  my ($w,$f,$elem) = @_;
  182.  $w->{'BODY'} = 0;
  183.  return $w;
  184. }
  185.  
  186. sub a
  187. {
  188.  my ($h,$f,$elem) = @_;
  189.  if (!$f)
  190.   {
  191.    my $w = $h->{widget};
  192.    my $href = $elem->attr('href');
  193.    my $name = $elem->attr('name');
  194.    if ($href)
  195.     {
  196.      my $tag  = $h->GenTag('HREF',-underline => 1);
  197.      $w->tagAdd($tag,$elem->{'_Start_'},$elem->{'_End_'});
  198.      $w->tagBind($tag,'<Button-1>',[$w,'HREF',$href,'GET']);
  199.      $w->tagBind($tag,'<Enter>',[$w,'Callback','-showlink',$href]);
  200.     }
  201.    if ($name)
  202.     {
  203.      $w->tagAdd($name,$elem->{'_Start_'},$elem->{'_End_'});
  204.      push(@{$h->{'GenTag'}},$name);
  205.     }
  206.   }
  207.  return $f;
  208. }
  209.  
  210. sub li
  211. {
  212.  my ($w,$f,$elem) = @_;
  213.  if ($f)
  214.   {
  215.    my $list = $elem->enclosing(1,qw(ul ol dir menu));
  216.    if ($list->tag eq 'ol')
  217.     {
  218.      my $n = ++$list->{Num};
  219.      $w->insert('insert',"\n $n. ");
  220.     }
  221.    else
  222.     {
  223.      # $w->insert('insert',"\n \xA8 ",['symbol']);
  224.      $w->insert('insert',"\n \xB7 ",['symbol']);
  225.     }
  226.   }
  227.  return $w;
  228. }
  229.  
  230. sub dt
  231. {
  232.  my ($w,$f,$elem) = @_;
  233.  $w->nl(1+$f);
  234.  return $w;
  235. }
  236.  
  237. sub dd
  238. {
  239.  my ($w,$f,$elem) = @_;
  240.  $w->nl(1);
  241.  return $w;
  242. }
  243.  
  244.  
  245. sub tr
  246. {
  247.  my ($w,$f,$elem) = @_;
  248.  my $table = $elem->enclosing(1,'table');
  249.  if ($f)
  250.   {
  251.    $elem->{Col} = 0;
  252.   }
  253.  else
  254.   {
  255.    $table->{widget}->configure(-columns => $elem->{Col});
  256.    $table->{Row}++;
  257.   }
  258.  return $w;
  259.  
  260. sub p
  261. {
  262.  my ($w,$f,$elem) = @_;
  263.  $w->{'BODY'} = 1;
  264.  $w->nl(2);
  265.  return $w;
  266. }
  267.  
  268. sub br
  269. {
  270.  my ($w,$f,$elem) = @_;
  271.  $w->{'BODY'} = 1;
  272.  if (@{$w->{'Text'}})
  273.   {
  274.    $w->{'Text'}[-1]->Call("\n");
  275.   }
  276.  else
  277.   {
  278.    $w->nl(1);
  279.   }
  280.  return $w;
  281. }
  282.  
  283. sub hr
  284. {
  285.  my ($h,$f,$elem) = @_;
  286.  my $w = $h->{widget};
  287.  my $r = $w->Frame(-height => 2, 
  288.                    -width => $w->cget('-width')*140,
  289.                    -borderwidth => 1, -relief => 'sunken',
  290.                   );
  291.  $h->nl(1);
  292.  $w->window('create','insert','-window' => $r, -pady => 0, -padx => 0);
  293.  $h->{NL} = 0;
  294.  $h->{'BODY'} = 1;
  295.  $h->nl(1);
  296.  return $f;
  297. }
  298.  
  299. sub DeEscape
  300. {
  301.  my ($var,$text) = @_;
  302.  $$var .= HTML::Entities::decode($text);
  303. }
  304.  
  305. sub td
  306. {
  307.  my ($w,$f,$elem) = @_;
  308.  my $row   = $elem->enclosing(1,'tr');
  309.  my $table = $row->enclosing(1,'table');
  310.  if ($f)
  311.   {
  312.    $elem->{Text} = "";
  313.    $w->TextHandler([\&DeEscape,\$elem->{Text}]);
  314.   }
  315.  else
  316.   {
  317.    my $w = $table->{widget};
  318.    my @elem = ();
  319.    my $al = $elem->{ALIGN};
  320.    if (defined $al)
  321.     {
  322.      push(@elem,-justify => 'right',-anchor => 'e') if ($al =~ /RIGHT/i);
  323.     }
  324.    $w->Create($table->{Row},$row->{Col},'Message',-aspect => 300, 
  325.            -relief => 'ridge', -text => $elem->{Text},@elem);
  326.    pop(@{$w->{'Text'}});
  327.    $row->{Col}++;
  328.   }
  329.  return $w;
  330.  
  331. sub table
  332. {
  333.  my ($h,$f,$elem) = @_;
  334.  if ($f)
  335.   {
  336.    my $w = $h->Widget;
  337.    $elem->{widget} = $w->Scrolled('Table');
  338.    $elem->{Row}    = 0;
  339.    $w->window('create','insert',-window => $elem->{widget});
  340.    print "Table:",join(',',%$elem),"\n";
  341.   }
  342.  else
  343.   {
  344. #   $elem->{widget}->configure(-rows => $elem->{Row});
  345.   }
  346.  return $h;
  347. }
  348.  
  349. sub form
  350. {
  351.  my ($w,$f,$form) = @_;
  352.  $w->{'BODY'} = 1;
  353.  if ($f)
  354.   {
  355.    $form->{OldForm} = $w->CurrentForm;
  356.    bless $form,'Tk::HTML::Form';
  357.    push(@{$w->{'FORM'}},$form);
  358.    $form->{'Values'}  = [];
  359.    $form->{'Owner'} = $w;
  360.    $w->CurrentForm($form);
  361.   }
  362.  else
  363.   {
  364.    my $what;
  365.    my @val = ();
  366.    foreach $what (@{$form->{'Values'}})
  367.     {
  368.      my $val = $what->[1];
  369.      if (ref($val))
  370.       {
  371.        $val = $val->Call();
  372.       }
  373.      push(@val,$val);
  374.     }
  375.    $form->{'Reset'} = \@val;
  376.    $w->CurrentForm(delete $form->{OldForm});
  377.   }
  378.  $w->nl(1);
  379.  return $w;
  380. }
  381.  
  382. sub input 
  383. {
  384.  my($w,$f,$elem) = @_;
  385.  my $form = $w->CurrentForm;
  386.  my $type = $elem->attr('type');
  387.  $elem->attr(type => ($type = 'TEXT')) unless (defined $type);
  388.  $type = "\U$type";
  389.  $form->$type($elem);
  390.  return $w;
  391. }
  392.  
  393. sub option 
  394. {
  395.  my ($w,$f,$elem) = @_;
  396.  if ($f)
  397.   {
  398.    push(@{$w->{'option'}},$elem);
  399.   }
  400.  else
  401.   {
  402.    pop(@{$w->{'option'}});
  403.   }
  404.  return $f;
  405. }
  406.  
  407. sub OptionText
  408. {
  409.  my ($h,$mb,$text) = @_;
  410.  my $elem = $h->{'option'}[-1];
  411.  if (defined $elem)
  412.   {
  413.    my $val = $elem->attr('value');
  414.    $text =~ s/^\s+//;
  415.    $text =~ s/\s+$//;
  416.    $elem->attr('value' => $text) unless ($val);
  417.    if ($elem->attr('value') ne $text)                         
  418.     {                                                     
  419.      $mb->{'FORM_MAP'} = {} unless (exists $mb->{'FORM_MAP'});
  420.      $mb->{'FORM_MAP'}{$text} = $elem->attr('value');
  421.     }                                                     
  422.    $mb->options([$text]);                                 
  423.    $mb->setOption($text) if ($elem->attr('selected'));
  424.   }
  425.  else
  426.   {
  427.    confess "$text outside option";
  428.   }
  429. }
  430.  
  431. sub MultipleText
  432. {
  433.  my ($h,$lb,$text) = @_;
  434.  $text =~ s/^\s+//;
  435.  $text =~ s/\s+$//;
  436.  my $elem = $h->{'option'}[-1];
  437.  if (defined $elem)
  438.   {
  439.    my $index = $lb->index('end');
  440.    $elem = {} unless (defined $elem);
  441.    $elem->{'VALUE'} = $text unless (exists $elem->{'VALUE'});
  442.    if ($elem->{'VALUE'} ne $text)
  443.     {                        
  444.      $lb->{'FORM_MAP'} = [] unless (exists $lb->{'FORM_MAP'});
  445.      $lb->{'FORM_MAP'}[$index] = $elem->{'VALUE'};
  446.     }                        
  447.    $lb->insert($index,$text);
  448.    $lb->selection('set',$index) if (defined $elem->{'SELECTED'});
  449.   }
  450.  else
  451.   {
  452.    confess "$text outside option";
  453.   }
  454. }
  455.  
  456. sub select 
  457. {
  458.  my($h,$f,$elem) = @_;
  459.  if ($f) 
  460.   {
  461.    $h->{NL} = 0;
  462.    my $w = $h->Widget;
  463.    my $form = $h->CurrentForm;
  464.    $h->{'option'} = [];
  465.    if ($elem->attr('multiple') || (defined $elem->{'size'} && $elem->{'size'} > 1)) 
  466.     {
  467.      my $size = $elem->attr('size');
  468.      $size = 15 unless ($size);
  469.      my $e = $w->Scrolled('Listbox',-height => $size,-scrollbars => 'e');
  470.      $e->configure(-selectmode => 'multiple') if $elem->attr('multiple');
  471.      $w->window('create','insert',-window => $e);
  472.      if (defined $form)
  473.       {
  474.        my $var = $form->Variable($elem);
  475.        $$var   = Tk::Callback->new([\&Tk::HTML::Form::MultipleValue,$e]);
  476.       }
  477.      $h->TextHandler([\&MultipleText,$h,$e]);
  478.     } 
  479.    else 
  480.     {
  481.      my $buttonvar = "__not__";
  482.      my $mb = $w->Optionmenu(-textvariable => \$buttonvar,-relief => 'raised');
  483.      $w->window('create','insert',-window => $mb);
  484.      if (defined $form)
  485.       {
  486.        my $var = $form->Variable($elem);
  487.        $$var   = Tk::Callback->new([\&Tk::HTML::Form::OptionValue,$mb,\$buttonvar]);
  488.       }
  489.      $h->TextHandler([\&OptionText,$h,$mb]);
  490.     }
  491.   } 
  492.  else 
  493.   {
  494.    pop(@{$h->{'Text'}});
  495.    delete $h->{'option'};
  496.   }
  497.  return $f;
  498. }
  499.  
  500. sub textarea 
  501. {
  502.   my($h,$f,$elem) = @_;
  503.   if ($f) 
  504.    {
  505.     my $rows = $elem->attr('rows') || 20;
  506.     my $cols = $elem->attr('cols') || 12;
  507.     my $form = $h->CurrentForm;
  508.     my $w = $h->Widget;
  509.     $elem->{'NAME'} = '__inconnu__' if ! defined $elem->{'NAME'};
  510.     my $t = $w->Scrolled('Text',-wrap => 'none',  -relief => 'sunken', -scrollbars => 'se',
  511.                           -width => $cols, -height => $rows);
  512.     $w->{'textarea'} = $t;
  513.     if (defined $form)
  514.      {
  515.       my $var = $form->Variable($elem);
  516.       $$var   = Tk::Callback->new([$t,'Contents']);
  517.      }
  518.     $w->window('create','insert',-window => $t);
  519.     $h->{NL} = 0;
  520.     $h->TextHandler([$t,'insert','end']);
  521.    } 
  522.   else 
  523.    {
  524.     pop(@{$h->{'Text'}});
  525.    }
  526.  return $f;
  527. }
  528.   
  529. sub base 
  530. {
  531.  print STDERR "base(",join(',',@_),")\n";
  532.  my($h,$f,$elem) = @_;
  533.  $h->{'BODY'} = 0;
  534.  print STDERR "base elem=$elem\n";
  535.  my $w = $h->Widget;
  536.  $w->base($elem->attr('href'));
  537.  return 1
  538. }
  539.  
  540. sub isindex 
  541. {
  542.  my($h,$f,$elem) = @_;
  543.  $h->{'BODY'} = 0;
  544.  if ($f)
  545.   {
  546.    my $w = $h->{widget};
  547.    $h->hr($f,$elem);
  548.    $w->insert('end','This is a searchable index, enter keyword(s) : ');
  549.    my $e = $w->Entry;
  550.    $e->bind('<Return>',[$w,'call_ISINDEX',$e]);
  551.    $w->window('create','end',-window => $e);
  552.    $h->{NL} = 0;    
  553.    $h->hr($f,$elem);
  554.   }
  555.  return $f;
  556. }
  557.  
  558. sub img
  559. {
  560.  my ($h,$f,$elem) = @_;
  561.  my $w = $h->{widget};
  562.  my $alt = $elem->attr('alt') || ">>Missing IMG<<";
  563.  my $l = $w->Label(-text => $alt);
  564.  my $al = $elem->attr('align');
  565.  my @al = (-align => 'baseline');
  566.  if (defined $al)
  567.   {
  568.    my $al = "\U$al";
  569.    if ($al eq "MIDDLE")
  570.     {
  571.      @al = (-align => 'center') 
  572.     }
  573.    elsif ($al eq "BOTTOM")
  574.     {
  575.      @al = (-align => 'baseline') 
  576.     }
  577.    elsif ($al eq "TOP")
  578.     {
  579.      @al = (-align => 'top') 
  580.     }
  581.    else
  582.     {
  583.      print "Align '$al'?\n";
  584.     }
  585.   }
  586.  $w->window('create','insert','-window' => $l, @al);
  587.  $h->{NL} = 0;                
  588.  my $src = $elem->attr('src');
  589.  $w->FindImage($src,$l) if ($src);
  590.  my $a = $elem->enclosing(0,'a');
  591.  if ($a || $elem->attr('image'))
  592.   {
  593.    $l->configure('-cursor' => "top_left_arrow", -borderwidth => 3, -relief => 'raised');
  594.    if ($elem->attr('ismap') && $a)
  595.     {
  596.      $l->bind('<1>',[$w,'IMG_CLICK',$l,'ISMAP',$a->attr('href')]);
  597.     } 
  598.    elsif ($elem->attr('image'))
  599.     {
  600.      $l->bind('<1>',[$w,'IMG_CLICK',$l,'IMAGE',$f,$elem->attr('name')]);
  601.     } 
  602.    elsif ($a)
  603.     {
  604.      $l->bind('<1>',[$w,'IMG_CLICK',$l,'AREF',$a->attr('href')]);
  605.     }
  606.   }
  607.  return $f;
  608. }
  609.  
  610. sub title
  611. {
  612.  my ($w,$f,$elem) = @_;
  613.  if ($f)
  614.   {
  615.    $w->{TITLE} = "";
  616.    $w->TextHandler(sub { $w->{TITLE} .= shift });
  617.    $w->{'BODY'} = 0;
  618.   }
  619.  else
  620.   {
  621.    $w->{widget}->toplevel->title($w->{TITLE});
  622.    pop(@{$w->{'Text'}});
  623.   }
  624.  return $w;
  625. }
  626.  
  627. sub Heading
  628. {
  629.  my ($w,$f,$elem) = @_;
  630.  $w->nl(2);
  631.  if (!$f)
  632.   {
  633.    my $tag = uc $elem->tag;
  634.    my $align = $elem->attr('align');
  635.    $w->{widget}->tagConfigure($tag,-justify => lc($align)) if ($align);
  636.    $w->ElemTag($elem);
  637.   }
  638.  return $w;
  639. }
  640.  
  641. sub blockquote
  642. {
  643.  my ($w,$f,$elem) = @_;
  644.  if ($f)
  645.   {
  646.    $w->nl(1);
  647.   }
  648.  else
  649.   {
  650.    $w->ElemTag($elem);
  651.    $w->nl(1);
  652.   }
  653.  return $w;
  654. }
  655.  
  656. sub center
  657. {
  658.  my ($w,$f,$elem) = @_;
  659.  if ($f)
  660.   {
  661.    $w->nl(1);
  662.   }
  663.  else
  664.   {
  665.    $w->ElemTag($elem);
  666.    $w->nl(1);
  667.   }
  668.  return $w;
  669. }
  670.  
  671. sub DoesNothing
  672. {
  673.  my ($w,$f,$elem) = @_;
  674.  return $f;
  675. }
  676.  
  677. sub pre
  678. {
  679.  my ($h,$f,$elem) = @_;
  680.  $h->{'PRE'} = $f;
  681.  if (!$f)
  682.   {
  683.    $h->tagAdd('CODE',$elem->{'_Start_'},$elem->{'_End_'});
  684.   }
  685.  return $f;
  686. }
  687.  
  688. sub List
  689. {
  690.  my ($w,$f,$elem) = @_;
  691.  if ($f)
  692.   {
  693.    $elem->{Num} = 0;
  694.    push(@{$w->{'List'}},['LI' . $elem->tag,0,$elem->{'_Start_'}]);
  695.    my $depth = @{$w->{'List'}};
  696.    if ($depth > 1) 
  697.     {
  698.      my $len = ($depth - 1) * 20;
  699.      my $tag = $w->GenTag($elem->tag . "temp",
  700.                           -lmargin1 => $len, 
  701.                           -lmargin2 => $len,
  702.                           -rmargin => $len);
  703.      $w->tagAdd($tag,${${$w->{'List'}}[$depth-2]}[2],${${$w->{'List'}}[$depth-1]}[2]);
  704.     }
  705.   }
  706.  else
  707.   {
  708.    my $depth = @{$w->{'List'}};
  709.    if ($depth > 1) 
  710.     {
  711.      ${${$w->{'List'}}[$depth - 2]}[2] = $elem->{'_End_'};
  712.      my $len = $depth * 20;
  713.      my $tag = $w->GenTag($elem->tag,
  714.                           -lmargin1 => $len, 
  715.                           -lmargin2 => $len,
  716.                           -rmargin => $len);
  717.      $w->tagAdd($tag,${${$w->{'List'}}[$depth - 1]}[2],$elem->{'_End_'});
  718.     }
  719.    pop(@{$w->{'List'}});
  720.   }
  721.  return $f;
  722. }
  723.  
  724. sub traverse
  725. {
  726.  my ($h,$elem,$start,$depth) = @_;
  727.  # print ' 'x$depth,$start," ",(ref $elem) ? $elem->tag : $elem,"\n";
  728.  if (ref $elem)
  729.   {
  730.    my $tag = $elem->tag;
  731.    my $posn = $h->{widget}->index('insert');
  732.    if ($start)
  733.     {
  734.      $elem->{'_Start_'} = $posn;
  735.     }
  736.    else
  737.     {
  738.      $elem->{'_End_'} = $posn;
  739.     }
  740.    return $h->$tag($start,$elem);
  741.   }
  742.  else
  743.   {
  744.    my $text = $elem;
  745.    if (defined(substr($text,0,1)))
  746.     {
  747.      if (@{$h->{'Text'}})
  748.       {
  749.        $h->{'Text'}[-1]->Call($text);
  750.       }
  751.      else
  752.       {
  753.        return unless ($h->{'BODY'});
  754.        unless ($h->{'PRE'})
  755.         {
  756.          $text =~ s/\n/ /mg;
  757.          $text =~ s/^\s+//g;
  758.          $text =~ s/\s\s+/ /g;
  759.          $text =~ s/\s+$//g;
  760.         }
  761.        $text = HTML::Entities::decode($text);
  762.        if (length(substr($text,0,1)))
  763.         {
  764.          my $w = $h->{'widget'};
  765.          $w->insert('insert',' ',qw(text)) unless ($h->{NL});
  766.          $w->insert('insert',$text,qw(text));
  767.          $h->{NL} = 0;                
  768.          $h->{NL} = 1 if ($text =~ /\n$/);
  769.         }
  770.       }
  771.     }
  772.    return 1;
  773.   }
  774. }
  775.  
  776.  
  777.