Changeset 3962 in subversion


Ignore:
Timestamp:
Sep 14, 2010 4:40:51 AM (3 years ago)
Author:
alec
Message:
  • Fix format=flowed handling (#1486989) + small improvements in plain messages parsing
Location:
trunk/roundcubemail
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r3960 r3962  
    2222- Fix handling of charsets with LATIN-* label 
    2323- Fix messages background image handling in some cases (#1486990) 
     24- Fix format=flowed handling (#1486989) 
    2425 
    2526RELEASE 0.4 
  • trunk/roundcubemail/program/include/rcube_message.php

    r3959 r3962  
    215215            if ($mimetype == 'text/plain') { 
    216216                $out = $this->imap->get_message_part($this->uid, $mime_id, $part); 
    217          
     217 
    218218                // re-format format=flowed content 
    219219                if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') 
     
    222222            } 
    223223            else if ($mimetype == 'text/html') { 
    224                 $html_part = $this->imap->get_message_part($this->uid, $mime_id, $part); 
     224                $out = $this->imap->get_message_part($this->uid, $mime_id, $part); 
    225225 
    226226                // remove special chars encoding 
    227227                $trans = array_flip(get_html_translation_table(HTML_ENTITIES)); 
    228                 $html_part = strtr($html_part, $trans); 
     228                $out = strtr($out, $trans); 
    229229 
    230230                // create instance of html2text class 
    231                 $txt = new html2text($html_part); 
     231                $txt = new html2text($out); 
    232232                $out = $txt->get_text(); 
    233                 break; 
    234233            } 
    235234        } 
     
    605604    public static function unfold_flowed($text) 
    606605    { 
    607         return preg_replace( 
    608             array('/-- (\r?\n)/',   '/^ /m',  '/(.) \r?\n/',  '/--%SIGEND%(\r?\n)/'), 
    609             array('--%SIGEND%\\1',  '',       '\\1 ',         '-- \\1'), 
    610             $text); 
     606        $text = preg_split('/\r?\n/', $text); 
     607        $last = -1; 
     608        $q_level = 0; 
     609 
     610        foreach ($text as $idx => $line) { 
     611            if ($line[0] == '>' && preg_match('/^(>+\s*)/', $line, $regs)) { 
     612                $q = strlen(str_replace(' ', '', $regs[0])); 
     613                $line = substr($line, strlen($regs[0])); 
     614 
     615                if ($q == $q_level && isset($text[$last]) 
     616                    && $text[$last][strlen($text[$last])-1] == ' ' 
     617                ) { 
     618                    $text[$last] .= $line; 
     619                    unset($text[$idx]); 
     620                } 
     621                else { 
     622                    $last = $idx; 
     623                } 
     624            } 
     625            else { 
     626                $q = 0; 
     627                if ($line == '-- ') { 
     628                    $last = $idx; 
     629                } 
     630                else { 
     631                    // remove space-stuffing 
     632                    $line = preg_replace('/^\s/', '', $line); 
     633 
     634                    if (isset($text[$last]) 
     635                        && $text[$last] != '-- ' 
     636                        && $text[$last][strlen($text[$last])-1] == ' ' 
     637                    ) { 
     638                        $text[$last] .= $line; 
     639                        unset($text[$idx]); 
     640                    } 
     641                    else { 
     642                        $text[$idx] = $line; 
     643                        $last = $idx; 
     644                    } 
     645                } 
     646            } 
     647            $q_level = $q; 
     648        } 
     649 
     650        return implode("\r\n", $text); 
    611651    } 
    612652 
     
    617657    public static function format_flowed($text, $length = 72) 
    618658    { 
    619         $out = ''; 
    620      
    621         foreach (preg_split('/\r?\n/', trim($text)) as $line) { 
    622             // don't wrap quoted lines (to avoid wrapping problems) 
    623             if ($line[0] != '>') 
    624                 $line = rc_wordwrap(rtrim($line, "\r\n"), $length - 1, " \r\n"); 
    625  
    626             $out .= $line . "\r\n"; 
    627         } 
    628      
    629         return $out; 
     659        $text = preg_split('/\r?\n/', $text); 
     660 
     661        foreach ($text as $idx => $line) { 
     662            if ($line != '-- ') { 
     663                if ($line[0] == '>' && preg_match('/^(>+)/', $line, $regs)) { 
     664                    $prefix = $regs[0]; 
     665                    $level = strlen($prefix); 
     666                    $line  = rtrim(substr($line, $level)); 
     667                    $line  = $prefix . rc_wordwrap($line, $length - $level - 2, " \r\n$prefix "); 
     668                } 
     669                else { 
     670                    $line = ' ' . rc_wordwrap(rtrim($line), $length - 2, " \r\n "); 
     671                } 
     672 
     673                $text[$idx] = $line; 
     674            } 
     675        } 
     676 
     677        return implode("\r\n", $text); 
    630678    } 
    631679 
  • trunk/roundcubemail/program/steps/mail/func.inc

    r3960 r3962  
    736736  // plaintext postprocessing 
    737737  if ($part->ctype_secondary == 'plain') 
    738     $body = rcmail_plain_body($body); 
     738    $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed'); 
    739739 
    740740  // allow post-processing of the message body 
     
    748748 * Handle links and citation marks in plain text message 
    749749 * 
    750  * @param string  Plain text string  
     750 * @param string  Plain text string 
     751 * @param boolean Text uses format=flowed 
     752 * 
    751753 * @return string Formatted HTML string 
    752754 */ 
    753 function rcmail_plain_body($body) 
     755function rcmail_plain_body($body, $flowed=false) 
    754756{ 
    755757  // make links and email-addresses clickable 
    756   $replacements = new rcube_string_replacer; 
     758  $replacer = new rcube_string_replacer; 
    757759 
    758760  // search for patterns like links and e-mail addresses 
    759   $body = preg_replace_callback($replacements->link_pattern, array($replacements, 'link_callback'), $body); 
    760   $body = preg_replace_callback($replacements->mailto_pattern, array($replacements, 'mailto_callback'), $body); 
     761  $body = preg_replace_callback($replacer->link_pattern, array($replacer, 'link_callback'), $body); 
     762  $body = preg_replace_callback($replacer->mailto_pattern, array($replacer, 'mailto_callback'), $body); 
    761763 
    762764  // split body into single lines 
    763765  $a_lines = preg_split('/\r?\n/', $body); 
    764   $q_lines = array(); 
    765766  $quote_level = 0; 
     767  $last = -1; 
    766768 
    767769  // find/mark quoted lines... 
    768770  for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) { 
    769     $q = 0; 
    770  
    771771    if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) { 
    772772      $q = strlen(preg_replace('/\s/', '', $regs[0])); 
    773         $a_lines[$n] = substr($a_lines[$n], strlen($regs[0])); 
     773      $a_lines[$n] = substr($a_lines[$n], strlen($regs[0])); 
    774774 
    775775      if ($q > $quote_level) 
    776         $q_lines[$n]['quote'] = $q - $quote_level; 
     776        $a_lines[$n] = $replacer->get_replacement($replacer->add( 
     777          str_repeat('<blockquote>', $q - $quote_level))) . $a_lines[$n]; 
    777778      else if ($q < $quote_level) 
    778         $q_lines[$n]['endquote'] = $quote_level - $q; 
    779     } 
    780     else if ($quote_level > 0) 
    781       $q_lines[$n]['endquote'] = $quote_level; 
     779        $a_lines[$n] = $replacer->get_replacement($replacer->add( 
     780          str_repeat('</blockquote>', $quote_level - $q))) . $a_lines[$n]; 
     781      else if ($flowed) { 
     782        // previous line is flowed 
     783        if (isset($a_lines[$last]) 
     784          && $a_lines[$last][strlen($a_lines[$last])-1] == ' ') { 
     785          // merge lines (and remove space-stuffing) 
     786          $a_lines[$last] .= $a_lines[$n]; 
     787          unset($a_lines[$n]); 
     788        } 
     789        else 
     790          $last = $n; 
     791      } 
     792    } 
     793    else { 
     794      $q = 0; 
     795      if ($flowed) { 
     796        // sig separator - line is fixed 
     797        if ($a_lines[$n] == '-- ') { 
     798          $last = $n; 
     799        } 
     800        else { 
     801          // remove space-stuffing 
     802          if ($a_lines[$n][0] == ' ') 
     803            $a_lines[$n] = substr($a_lines[$n], 1); 
     804 
     805          // previous line is flowed? 
     806          if (isset($a_lines[$last]) 
     807            && $a_lines[$last] != '-- ' 
     808            && $a_lines[$last][strlen($a_lines[$last])-1] == ' ' 
     809          ) { 
     810            $a_lines[$last] .= $a_lines[$n]; 
     811            unset($a_lines[$n]); 
     812          } 
     813          else { 
     814            $last = $n; 
     815          } 
     816        } 
     817        if ($quote_level > 0) 
     818          $a_lines[$last] = $replacer->get_replacement($replacer->add( 
     819            str_repeat('</blockquote>', $quote_level))) . $a_lines[$last]; 
     820      } 
     821      else if ($quote_level > 0) 
     822        $a_lines[$n] = $replacer->get_replacement($replacer->add( 
     823          str_repeat('</blockquote>', $quote_level))) . $a_lines[$n]; 
     824    } 
    782825 
    783826    $quote_level = $q; 
     
    785828 
    786829  // quote plain text 
    787   $body = Q(join("\n", $a_lines), 'replace', false); 
     830  $body = Q(join("\n", $a_lines), '', false); 
    788831 
    789832  // colorize signature 
    790   if (($sp = strrpos($body, '-- ')) !== false) 
    791     if (($sp == 0 || $body[$sp-1] == "\n") && $body[$sp+3] == "\n") { 
    792       $body = substr($body, 0, max(0, $sp)) 
    793         .'<span class="sig">'.substr($body, $sp).'</span>'; 
    794     } 
    795  
    796   // colorize quoted lines 
    797   $a_lines = preg_split('/\n/', $body); 
    798   foreach ($q_lines as $i => $q) 
    799     if ($q['quote']) 
    800       $a_lines[$i] = str_repeat('<blockquote>', $q['quote']) . $a_lines[$i]; 
    801     else if ($q['endquote']) 
    802       $a_lines[$i] = str_repeat('</blockquote>', $q['endquote']) . $a_lines[$i]; 
    803  
    804   // insert the links for urls and mailtos 
    805   $body = $replacements->resolve(join("\n", $a_lines)); 
    806      
     833  if (($sp = strrpos($body, "-- \n")) !== false) { 
     834    if (($sp == 0 || $body[$sp-1] == "\n")) { 
     835      // do not touch blocks with more that 10 lines 
     836      if (substr_count($body, "\n", $sp) < 10) 
     837        $body = substr($body, 0, max(0, $sp)) 
     838          .'<span class="sig">'.substr($body, $sp).'</span>'; 
     839    } 
     840  } 
     841 
     842  // insert url/mailto links and citation tags 
     843  $body = $replacer->resolve($body); 
     844 
    807845  return $body; 
    808 } 
    809  
    810  
    811 /** 
    812  * add a string to the replacement array and return a replacement string 
    813  */ 
    814 function rcmail_str_replacement($str, &$rep) 
    815 { 
    816   static $count = 0; 
    817   $rep[$count] = stripslashes($str); 
    818   return "##string_replacement{".($count++)."}##"; 
    819846} 
    820847 
     
    9831010        $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array( 
    9841011          'part' => $part, 'prefix' => '')); 
    985  
    986         // re-format format=flowed content 
    987         if ($part->ctype_secondary == "plain" && $part->ctype_parameters['format'] == "flowed") 
    988           $part->body = rcube_message::unfold_flowed($part->body); 
    9891012 
    9901013        $body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$CONFIG['prefer_html'])); 
  • trunk/roundcubemail/program/steps/mail/sendmail.inc

    r3923 r3962  
    462462  $message_body = $plugin['body']; 
    463463 
    464   // compose format=flowed content if enabled and not a reply message 
    465   if (empty($_SESSION['compose']['reply_msgid']) && ($flowed = $RCMAIL->config->get('send_format_flowed', true))) 
    466     $message_body = rcube_message::format_flowed($message_body, $LINE_LENGTH); 
     464  // compose format=flowed content if enabled 
     465  if ($flowed = $RCMAIL->config->get('send_format_flowed', true)) 
     466    $message_body = rcube_message::format_flowed($message_body, min($LINE_LENGTH+2, 79)); 
    467467  else 
    468468    $message_body = rc_wordwrap($message_body, $LINE_LENGTH, "\r\n"); 
Note: See TracChangeset for help on using the changeset viewer.