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 = '>|[\|\]+:]';
$StartFlowedQuote =
--- 45,50 ----
$HUrlExp = $Url . q/(?:&(?![gl]t;)|[^\s\(\)\|<>"'\&])+/ .
q/[^\.?!;,"'\|\[\]\(\)\s<>\&]/;
! $QuoteChars = '[>]';
! $HQuoteChars = '>';
$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 =~ /^((?:>)*)/;
! my $qd = $1;
if ($$data =~ s/^(.*(?:(?:\n|\r\n?)$qd(?!>).*)*\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 =~ /^((?:>)*)/;
if ($$data =~ s/^(.*(?:(?:\n|\r\n?)$qd(?!>).*)*\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('>');
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('>');
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