<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of Clearbricks.
# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
# All rights reserved.
#
# Clearbricks is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Clearbricks is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Clearbricks; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
#
# mail.convert
# This class converts mail body to xHTML in a descent fashion.
# It can also rewrap mail body.
class mailConvert
{
public $url_pattern = '%(?<![\[\|])(http|https|ftp|news):(//)?(.*?)(["\s\)]|>|<|\Z)%msu';
public static function toHTML($str)
{
$o = new self;
return $o->html(rtrim($str),true);
}
public static function rewrap($str,$l=72)
{
$o = new self;
return $o->wrap($str,$l);
}
public static function getSubject($str)
{
while (preg_match('/^re: /msiu',$str)) {
$str = preg_replace('/^re: /msiu','',$str);
}
return $str;
}
public function html($str,$with_signature=false)
{
$res = '';
$signature = '';
if ($with_signature && preg_match('/^(-- \r?\n.+?)\Z/msu',$str,$m))
{
$m[1] = preg_replace('/^-- \r?\n/msu','',$m[1]);
$signature = '<pre class="signature">'.$this->htmlParseBlock($m[1]).'</pre>';
$str = preg_replace('/^-- \r?\n(.+?)\Z/msu','',$str);
$str = rtrim($str);
}
foreach ($this->getTockens($str) as $t)
{
switch ($t['type'])
{
case 'block':
$t['content'] = $this->htmlParseBlock($t['content']);
$res .= '<pre>'.$t['content']."</pre>\n";
break;
case 'quote':
$res .= "<blockquote>\n".$this->html($t['content'])."</blockquote>\n\n";
break;
}
}
return $res.$signature;
}
public function wrap($str,$l=72)
{
$str = $this->prepareString($str);
$res = '';
foreach (explode("\n",$str) as $line)
{
$sep = "\n";
if (preg_match('/^([>\|]+\s*)/su',$line,$m)) {
$sep .= $m[1];
}
$line = wordwrap($line,$l,$sep,false)."\n";
$res .= $line;
}
return $res;
}
protected function prepareString($str)
{
return preg_replace('/\r?\n/msu',"\n",$str);
}
protected function getTockens($str)
{
$str = $this->prepareString($str);
$tockens = array();
$type = null;
$id = -1;
foreach (explode("\n",$str) as $line)
{
if (preg_match('/^(?:\s*)(?:>|\|)(?:\s?)(.*?)$/su',$line,$m))
{
if ($type != 'quote' && !trim($m[1])) {
continue;
}
if ($type == 'quote') {
$tockens[$id]['content'] .= $m[1]."\n";
} else {
$id++;
$type = 'quote';
$tockens[$id]['type'] = $type;
$tockens[$id]['content'] = $m[1]."\n";
}
}
# Empty line
elseif (preg_match('/^\s*$/su',$line))
{
if ($type == 'block') {
$tockens[$id]['content'] .= "\n";
}
}
# Defaults to block
else
{
if ($type == 'block') {
$tockens[$id]['content'] .= $line."\n";
} else {
$id++;
$type = 'block';
$tockens[$id]['type'] = $type;
$tockens[$id]['content'] = $line."\n";
}
}
}
foreach ($tockens as $i => $t)
{
$tockens[$i]['content'] = preg_replace('/\n$/su','',$t['content']);
}
return $tockens;
}
protected function htmlParseBlock($str)
{
$str = html::escapeHTML($str);
# Transform links
$str = preg_replace_callback($this->url_pattern,array($this,'htmlUrlHandler'),$str);
# Transform * / _ strings (does not work, may transform links href)
#$str = preg_replace_callback('%([\*_/])([\w\s]+?)([\*_/])%msu',array($this,'htmlFormatHandler'),$str);
return $str;
}
protected function htmlUrlHandler($m)
{
$url = $m[1].':'.html::decodeEntities($m[2].$m[3]);
$content = $url;
$title = '';
if (strlen($url) > 42) {
$content = substr($url,0,42).'...';
$title = ' title="'.html::escapeHTML($url).'"';
}
return '<a href="'.html::escapeHTML($url).'"'.$title.'>'.html::escapeHTML($content).'</a>'.$m[4];
}
protected function htmlFormatHandler($m)
{
switch ($m[1])
{
case '*':
return '<strong>'.$m[2].'</strong>';
case '/':
return '<em>'.$m[2].'</em>';
case '_':
return '<ins>'.$m[2].'</ins>';
}
}
}
?>