mhonarc-commits
[Top] [All Lists]

CVS: mhonarc/MHonArc/lib mhtxtplain.pl,2.24,2.25

2002-10-26 15:26:28
Update of /cvsroot/mhonarc/mhonarc/MHonArc/lib
In directory subversions:/tmp/cvs-serv17702/lib

Modified Files:
	mhtxtplain.pl 
Log Message:
* BUG FIX: #1518.
+ Added "fancyquote" option to provide highlight of quoted text
  similiar to text/plain;format=flowed data.
+ Added "disableflowed" option to disable the flowed data
  conversion.  Data will be converted as regular text/plain.
+ Added "quoteclass=<classname>" option to specify a CSS classname
  to assign to BLOCKQUOTE elements added when processing flowed
  data or when "fancyquote" is active.  This suppresses inline
  style generation.
o Flowed conversion fallback error handling improved so data is
  not lost.  However, the fallack code should never be reached.


Index: mhtxtplain.pl
===================================================================
RCS file: /cvsroot/mhonarc/mhonarc/MHonArc/lib/mhtxtplain.pl,v
retrieving revision 2.24
retrieving revision 2.25
diff -C2 -r2.24 -r2.25
*** mhtxtplain.pl	10 Oct 2002 22:27:19 -0000	2.24
--- mhtxtplain.pl	26 Oct 2002 22:26:20 -0000	2.25
***************
*** 35,38 ****
--- 35,43 ----
  require 'readmail.pl';
  
+ sub Q_FIXED()  { 0; }
+ sub Q_SIMPLE() { 1; }
+ sub Q_FANCY()  { 2; }
+ sub Q_FLOWED() { 3; }
+ 
  $Url    	= '(http://|https://|ftp://|afs://|wais://|telnet://|ldap://' .
  		   '|gopher://|news:|nntp:|mid:|cid:|mailto:|prospero:)';
***************
*** 40,45 ****
  $HUrlExp        = $Url . q/(?:&(?![gl]t;)|[^\s\(\)\|<>"'\&])+/ .
  			 q/[^\.?!;,"'\|\[\]\(\)\s<>\&]/;
! $QuoteChars	= '[>\|\]+:]';
! $HQuoteChars	= '&gt;|[\|\]+:]';
  
  $StartFlowedQuote =
--- 45,50 ----
  $HUrlExp        = $Url . q/(?:&(?![gl]t;)|[^\s\(\)\|<>"'\&])+/ .
  			 q/[^\.?!;,"'\|\[\]\(\)\s<>\&]/;
! $QuoteChars	= '[>]';
! $HQuoteChars	= '&gt;';
  
  $StartFlowedQuote =
***************
*** 66,69 ****
--- 71,81 ----
  ##	default=set 	Default charset to use if not set.
  ##
+ ##	disableflowed
+ ##			Ignore flowed formatting for message text
+ ##			denoted with flowed formatting.
+ ##
+ ##	fancyquote	Highlight quoted text with vertical bar in left
+ ##			margin.
+ ##
  ##      inlineexts="ext1,ext2,..."
  ##                      A comma separated list of message specified filename
***************
*** 87,90 ****
--- 99,105 ----
  ##	quote		Italicize quoted message text
  ##
+ ##	quoteclass	CSS classname for quoted text in flowed data or
+ ##			if fancyquote specified.  Overrides builtin style.
+ ##
  ##	target=name  	Set TARGET attribute for links if converting URLs
  ##			to links.  Defaults to _top.
***************
*** 219,228 ****
      }
  
!     my($charset, $nourl, $doquote, $igncharset, $nonfixed, $textformat,
         $keepspace, $maxwidth, $target, $defset, $xhtml);
      my(%asis) = ( );
  
      $nourl	= ($mhonarc::NOURL || ($args =~ /\bnourl\b/i));
-     $doquote	= ($args =~ /\bquote\b/i);
      $nonfixed	= ($args =~ /\bnonfixed\b/i);
      $keepspace	= ($args =~ /\bkeepspace\b/i);
--- 234,242 ----
      }
  
!     my($charset, $nourl, $igncharset, $nonfixed,
         $keepspace, $maxwidth, $target, $defset, $xhtml);
      my(%asis) = ( );
  
      $nourl	= ($mhonarc::NOURL || ($args =~ /\bnourl\b/i));
      $nonfixed	= ($args =~ /\bnonfixed\b/i);
      $keepspace	= ($args =~ /\bkeepspace\b/i);
***************
*** 241,246 ****
  
      ## Grab charset parameter (if defined)
!     if ( defined($fields->{'content-type'}[0]) and
! 	 $fields->{'content-type'}[0] =~ /\bcharset\s*=\s*([^\s;]+)/i ) {
  	$charset = lc $1;
  	$charset =~ s/['";\s]//g;
--- 255,260 ----
  
      ## Grab charset parameter (if defined)
!     if ( (defined($fields->{'content-type'}[0])) &&
! 	 ($fields->{'content-type'}[0] =~ /\bcharset\s*=\s*([^\s;]+)/i) ) {
  	$charset = lc $1;
  	$charset =~ s/['";\s]//g;
***************
*** 249,258 ****
      }
      ## Grab format parameter (if defined)
!     if ( defined($fields->{'content-type'}[0]) and
! 	 $fields->{'content-type'}[0] =~ /\bformat\s*=\s*([^\s;]+)/i ) {
  	$textformat = lc $1;
  	$textformat =~ s/['";\s]//g;
!     } else {
! 	$textformat = "fixed";
      }
  
--- 263,297 ----
      }
      ## Grab format parameter (if defined)
!     my $textformat = 'fixed';
!     if ( ($args !~ /\bdisableflowed\b/i) &&
! 	 (defined($fields->{'content-type'}[0])) &&
! 	 ($fields->{'content-type'}[0] =~ /\bformat\s*=\s*([^\s;]+)/i) ) {
  	$textformat = lc $1;
  	$textformat =~ s/['";\s]//g;
!     }
! 
!     my $startq    = "";
!     my $endq      = "";
!     my $css_class = "";
!     if ($args =~ /\bquoteclass=(\S+)/i) {
! 	$css_class = $1;
! 	$css_class =~ s/[^\w\.\-]//g;
!     }
! 
!     my $quote_style = Q_FIXED;
!     if ($textformat eq 'flowed') {
! 	$quote_style = Q_FLOWED;
! 	$startq = ($css_class) ? qq|<blockquote class="$css_class">| :
! 				 $StartFlowedQuote;
! 	$endq   = $EndFlowedQuote;
! 
!     } elsif ($args =~ /\bfancyquote\b/i) {
! 	$quote_style = Q_FANCY;
! 	$startq = ($css_class) ? qq|<blockquote class="$css_class">| :
! 				 $StartFlowedQuote;
! 	$endq   = $EndFlowedQuote;
! 
!     } elsif ($args =~ /\bquote\b/i) {
! 	$quote_style = Q_SIMPLE;
      }
  
***************
*** 294,298 ****
      }
  
!     if ($textformat eq 'flowed') {
  	# Initial code for format=flowed contributed by Ken Hirsch (May 2002).
  	# text/plain; format=flowed defined in RFC2646
--- 333,337 ----
      }
  
!     if ($quote_style == Q_FLOWED) {
  	# Initial code for format=flowed contributed by Ken Hirsch (May 2002).
  	# text/plain; format=flowed defined in RFC2646
***************
*** 300,307 ****
  	my $currdepth = 0;
  	my $ret='';
! 	$$data =~ s!^</?x-flowed>\r?\n>!!mg;
! 	while (length($$data)) {
! 	    $$data =~ /^((?:&gt;)*)/;
! 	    my $qd = $1;
  	    if ($$data =~ s/^(.*(?:(?:\n|\r\n?)$qd(?!&gt;).*)*\n?)//) {
  		# divide message into chunks by "quote-depth",
--- 339,345 ----
  	my $currdepth = 0;
  	my $ret='';
! 	$$data =~ s!^</?x-flowed>\r?\n!!mg;
! 	while (length($$data) > 0) {
! 	    my($qd) = $$data =~ /^((?:&gt;)*)/;
  	    if ($$data =~ s/^(.*(?:(?:\n|\r\n?)$qd(?!&gt;).*)*\n?)//) {
  		# divide message into chunks by "quote-depth",
***************
*** 312,344 ****
  		$chunk =~ s/^-- $/--/mg; # special case for '-- '
  
! 		if ($chunk =~ / \r?\n/) {
! 		    # Treat this chunk as format=flowed
! 		    # Lines that end with spaces are
! 		    # considered to have soft line breaks.
! 		    # Lines that end with no spaces are
! 		    # considered to have hard line breaks.
! 		    # XXX: Negative look-behind assertion not supported
! 		    #	   on older versions of Perl 5 (<5.6)
! 		    #$chunk =~ s/(?<! )(\r?\n|\Z)/<br>$1/g;
! 		    $chunk =~ s/(^|[^ ])(\r?\n|\Z)/$1<br>$2/mg;
  
- 		} else {
- 		    # Treat this chunk as format=fixed
- 		    if ($nonfixed) {
- 			$chunk =~ s/(\r?\n)/<br>$1/g;
- 			if ($keepspace) {
- 			    $chunk =~ s/^(.*)$/&preserve_space($1)/gem;
- 			}
  		    } else {
! 			$chunk = "<pre>" . $chunk . "</pre>\n";
  		    }
  		}
  		my $newdepth = length($qd)/length('&gt;');
  		if ($currdepth < $newdepth) {
! 		    $chunk = $StartFlowedQuote x
! 			     ($newdepth - $currdepth) . $chunk;
  		} elsif ($currdepth > $newdepth) {
! 		    $chunk = $EndFlowedQuote x
! 			     ($currdepth - $newdepth) . $chunk;
  		}
  		$currdepth = $newdepth;
--- 350,380 ----
  		$chunk =~ s/^-- $/--/mg; # special case for '-- '
  
! 		my @paras = split(/\r?\n\r?\n/, $chunk);
! 		my $para;
! 		$chunk = '';
! 		foreach $para (@paras) {
! 		    if (($para =~ / \r?\n/) || ($para =~ / \Z/)) {
! 			# flowed format
! 			$para =~ s/(^|[^ ])(\r?\n|\Z)/$1<br>$2/mg;
  
  		    } else {
! 			# fixed format
! 			if ($nonfixed) {
! 			    $para =~ s/(\r?\n)/<br>$1/g;
! 			    if ($keepspace) {
! 				$para =~ s/^(.*)$/&preserve_space($1)/gem;
! 			    }
! 			} else {
! 			    $para = '<pre>' . $para . '</pre>';
! 			}
  		    }
+ 		    $chunk .= $para;
  		}
+ 
  		my $newdepth = length($qd)/length('&gt;');
  		if ($currdepth < $newdepth) {
! 		    $chunk = $startq x ($newdepth - $currdepth) . $chunk;
  		} elsif ($currdepth > $newdepth) {
! 		    $chunk = $endq   x ($currdepth - $newdepth) . $chunk;
  		}
  		$currdepth = $newdepth;
***************
*** 351,360 ****
  		     qq/         Message-Id: <$MHAmsgid>\n/,
  		     qq/         Message Number: $MHAmsgnum\n/;
! 		$ret .= $$data;
  		last;
  	    }
  	}
  	if ($currdepth > 0) {
! 	    $ret .= $EndFlowedQuote x $currdepth;
  	}
  
--- 387,396 ----
  		     qq/         Message-Id: <$MHAmsgid>\n/,
  		     qq/         Message Number: $MHAmsgnum\n/;
! 		$ret .= '<pre>' . $$data . '</pre>';
  		last;
  	    }
  	}
  	if ($currdepth > 0) {
! 	    $ret .= $endq x $currdepth;
  	}
  
***************
*** 365,371 ****
  	$$data = $ret;
  
      } else {
! 	## Check for quoting
! 	if ($doquote) {
  	    $$data =~ s(_at_)^( ?${HQuoteChars})(.*)$(_at_)$1<i>$2</i>@gom;
  	}
--- 401,457 ----
  	$$data = $ret;
  
+     } elsif ($quote_style == Q_FANCY) {
+ 	my $currdepth = 0;
+ 	my $ret='';
+ 	while (length($$data) > 0) {
+ 	    my($qd) = $$data =~ /^((?:[ ]?(?:${HQuoteChars})[ ]?)*)/;
+ 	    my($qd_re) = "\Q$qd\E";
+ 	       $qd_re  =~ s/\\ /[ ]?/g;
+ 	    if ($$data =~ s/\A(.*(?:(?:\n|\r\n?)$qd_re
+ 			    (?![ ]?(?:${HQuoteChars}[ ]?)).*)*\r?\n?)//x) {
+ 		my $chunk = $1;
+ 		$chunk =~ s/^$qd_re//mg;
+ 		if ($nonfixed) {
+ 		    $chunk =~ s/(\r?\n)/<br>$1/g;
+ 		    if ($keepspace) {
+ 			$chunk =~ s/^(.*)$/&preserve_space($1)/gem;
+ 		    }
+ 		} else {
+ 		    $chunk = '<pre>' . $chunk . '</pre>';
+ 		}
+ 
+ 		$qd =~ s/\s+//g;
+ 		my $newdepth = html_length($qd);
+ 		if ($currdepth < $newdepth) {
+ 		    $chunk = $startq x ($newdepth - $currdepth) . $chunk;
+ 		} elsif ($currdepth > $newdepth) {
+ 		    $chunk = $endq   x ($currdepth - $newdepth) . $chunk;
+ 		}
+ 		$currdepth = $newdepth;
+ 		$ret .= $chunk;
+ 
+ 	    } else {
+ 		# The above regex should always match, but just in case...
+ 		warn qq/\n/,
+ 		     qq/Warning: Dequoting problem with entity data\n/,
+ 		     qq/         Message-Id: <$MHAmsgid>\n/,
+ 		     qq/         Message Number: $MHAmsgnum\n/;
+ 		$ret .= '<pre>' . $$data . '</pre>';
+ 		last;
+ 	    }
+ 	}
+ 	if ($currdepth > 0) {
+ 	    $ret .= $endq x $currdepth;
+ 	}
+ 
+ 	## Post-processing cleanup: makes things look nicer
+ 	$ret =~ s/<pre>\r?\n/<pre>/g;
+ 	$ret =~ s/\r?\n<\/pre>/<\/pre>/g;
+ 
+ 	$$data = $ret;
+ 
      } else {
! 	## Check for simple quoting
! 	if ($quote_style == Q_SIMPLE) {
  	    $$data =~ s(_at_)^( ?${HQuoteChars})(.*)$(_at_)$1<i>$2</i>@gom;
  	}
***************
*** 378,382 ****
  	    }
  	} else {
! 	    $$data = "<pre>" . $$data . "</pre>\n";
  	}
      }
--- 464,468 ----
  	    }
  	} else {
! 	    $$data = '<pre>' . $$data . '</pre>';
  	}
      }
***************
*** 464,467 ****
--- 550,561 ----
      }
      $new;
+ }
+ 
+ sub html_length {
+     my $len = length($_[0]);
+     while ($_[0] =~ /(\&[^;]+);/g) {
+ 	$len -= length($1);
+     }
+     $len;
  }
  

---------------------------------------------------------------------
To sign-off this list, send email to majordomo(_at_)mhonarc(_dot_)org with the
message text UNSUBSCRIBE MHONARC-DEV