package lib::util::Text2Html;
use strict;
use Exporter;
use vars qw /@ISA @EXPORT $DECIMAL_TO_HTML $HTML_TO_DECIMAL $NON_STD/;
@ISA = qw /Exporter/;
@EXPORT = qw /text2html html2text text2xml/;


# http://www.webreference.com/html/reference/character/isolat1.html
$NON_STD = {
    129 => '',
    130 => '&sbquo;',
    131 => '&fnof;',
    132 => '&bdquo;',
    133 => '&hellip;',
    134 => '&dagger;',
    135 => '&Dagger',
    136 => '^',
    137 => '%',
    138 => '&Scaron',
    139 => '&lt;',
    140 => '&OElig;',
    141 => '',
    143 => '',
    144 => '',
    145 => '&lsquo;',
    146 => '&rsquo;',
    147 => '&ldquo;',
    148 => '&rdquo;',
    149 => '&bull;',
    150 => '&ndash;',
    151 => '&mdash;',
    152 => '&tilde;',
    153 => '&trade;',
    154 => '&scaron;',
    155 => '&gt;',
    156 => '&oelig;',
    157 => '',
    158 => '',
    159 => '&Yuml;',
};


$DECIMAL_TO_HTML = {
     60 => '&lt;',
     62 => '&gt;',
    128 => '&euro;',
    160 => '&nbsp;',
    161 => '&iexcl;',
    162 => '&cent;',
    163 => '&pound;',
    164 => '&curren;',
    165 => '&yen;',
    166 => '&brvbar;',
    167 => '&sect;',
    168 => '&uml;',
    169 => '&copy;',
    170 => '&ordf;',
    171 => '&laquo;',
    172 => '&not;',
    173 => '&shy;',
    174 => '&reg;',
    175 => '&macr;',
    176 => '&deg;',
    177 => '&plusmn;',
    178 => '&sup2;',
    179 => '&sup3;',
    180 => '&acute;',
    181 => '&micro;',
    182 => '&para;',
    183 => '&middot;',
    184 => '&cedil;',
    185 => '&sup1;',
    186 => '&ordm;',
    187 => '&raquo;',
    188 => '&frac14;',
    189 => '&frac12;',
    190 => '&frac34;',
    191 => '&iquest;',
    192 => '&Agrave;',
    193 => '&Aacute;',
    194 => '&Acirc;',
    195 => '&Atilde;',
    196 => '&Auml;',
    197 => '&Aring;',
    198 => '&AElig;',
    199 => '&Ccedil;',
    200 => '&Egrave;',
    201 => '&Eacute;',
    202 => '&Ecirc;',
    203 => '&Euml;',
    204 => '&Igrave;',
    205 => '&Iacute;',
    206 => '&Icirc;',
    207 => '&Iuml;',
    208 => '&ETH;',
    209 => '&Ntilde;',
    210 => '&Ograve;',
    211 => '&Oacute;',
    212 => '&Ocirc;',
    213 => '&Otilde;',
    214 => '&Ouml;',
    215 => '&times;',
    216 => '&Oslash;',
    217 => '&Ugrave;',
    218 => '&Uacute;',
    219 => '&Ucirc;',
    220 => '&Uuml;',
    221 => '&Yacute;',
    222 => '&THORN;',
    223 => '&szlig;',
    224 => '&agrave;',
    225 => '&aacute;',
    226 => '&acirc;',
    227 => '&atilde;',
    228 => '&auml;',
    229 => '&aring;',
    230 => '&aelig;',
    231 => '&ccedil;',
    232 => '&egrave;',
    233 => '&eacute;',
    234 => '&ecirc;',
    235 => '&euml;',
    236 => '&igrave;',
    237 => '&iacute;',
    238 => '&icirc;',
    239 => '&iuml;',
    240 => '&eth;',
    241 => '&ntilde;',
    242 => '&ograve;',
    243 => '&oacute;',
    244 => '&ocirc;',
    245 => '&otilde;',
    246 => '&ouml;',
    247 => '&divide;',
    248 => '&oslash;',
    249 => '&ugrave;',
    250 => '&uacute;',
    251 => '&ucirc;',
    252 => '&uuml;',
    253 => '&yacute;',
    254 => '&thorn;',
    255 => '&yuml;',
};


$HTML_TO_DECIMAL = { reverse %{$DECIMAL_TO_HTML} };


sub text2xml
{
    my $data = join '', @_;
    my $res = "";
    for (my $i=0; $i < length ($data); $i++)
    {	
	my $char = substr $data, $i, 1;
	my $ord  = ord ($char);
	
	if ($ord > 127  or
	    $ord == 34 or $ord == 38 or
	    $ord == 60 or $ord == 62)
	{
	    $res .=  '&#' . $ord . ';';
	}
	else { $res .= $char }
    }
    
    return $res;
}


sub text2html
{
    my $data = join '', @_;
    my $res = "";
    for (my $i=0; $i < length ($data); $i++)
    {	
	my $char = substr $data, $i, 1;
	my $ord  = ord ($char);
	
	if (defined $NON_STD->{$ord})
	{
	    $res .= $NON_STD->{$ord};
	}
	elsif ($ord > 127  or
	       $ord == 34 or $ord == 38 or
	       $ord == 60 or $ord == 62)
	{
	    if (defined $DECIMAL_TO_HTML->{$ord})
	    {
		$res .= $DECIMAL_TO_HTML->{$ord};
	    }
	    else
	    {
		$res .=  '&#' . $ord . ';';
	    }
	}
	else { $res .= $char }
    }
    
    return $res;
}


sub html2text
{
    # roughly strip out tags
    my $data = join '', @_;
    $data =~ s/<[^>]*>//gs;
    
    my %entities = $data =~ /(\&(?:\#([0-9]+)|\w+)\;)/g;
    while ( my ($entity, $decimal) = each %entities)
    {
	my $val = ($decimal) ? chr ($decimal) : chr ($HTML_TO_DECIMAL->{lc ($entity)});
	$data =~ s/$entity/$val/gsim;
    }
    
    return $data;
}


1;
