2009-12-18 14 views
8

Conoscete una buona classe di conversione da HTML a testo semplice scritta in PHP?HTML a testo semplice (per e-mail)

Ne ho bisogno per convertire il corpo di posta HTML in corpo di testo semplice.

ho scritto semplice funzione, ma ho bisogno di più funzioni come le tabelle di conversione, collegamenti aggiungendo alla fine, la conversione di liste annidate ...

- riguarda
takeshin

+0

Perché non inviare messaggi in HTML? Capisco che le tabelle fasulle sono un po 'possibili in testo semplice, ma ogni lettore di e-mail al mondo legge HTML, perché non ti risparmi il problema della conversione inutile perché tu o qualcun altro si rifiuta di usare la posta HTML. – TravisO

+4

TravisO: Non tutti i lettori. E alcuni non convertono automaticamente l'HTML in testo normale. Per un utente l'HTML grezzo di solito non è bello da leggere :-) – Joey

+0

1996 è finito, usatelo.Ma ovviamente i tipi elitisti che detestano l'email HTML saranno i più vocali/disposti a votare quegli ideali. – TravisO

risposta

6
+2

E a che serve il markdown in una email di testo? –

+1

Uh, hai usato o letto qualcosa su Markdown? "L'obiettivo principale della progettazione della sintassi di formattazione di Markdown è renderlo il più leggibile possibile. ** L'idea è che un documento formattato con Markdown debba essere reso pubblicabile così com'è, come testo normale, senza apparire come se fosse stato contrassegnato con tag o istruzioni di formattazione. ** " – ceejayoz

+2

Markdownify è una buona soluzione, infatti. L'ho guardato prima, ma ho pensato che non converta le tabelle. Ma il problema era che ho provato su tabelle con '' attributi e alcuni stili CSS. Ho rimosso le didascalie manuali e le attribuzioni di classe e stile, e funziona bene. – takeshin

3

una particolare implementazione di posta del mittente qui intorno genera semplicemente lynx con l'HTML e utilizza la sua uscita per la versione del testo. Non è perfetto ma funziona. È inoltre possibile utilizzare links o elinks.

+0

Idea pulita, mi piace. – ceejayoz

+0

Sì, questo era già stato suggerito su StackOverflow, ma stavo chiedendo la creazione di PHP. Non ho accesso a Lynx sul mio server. Grazie. – takeshin

+0

Hai dimenticato di menzionare che hai bisogno dell'argomento '-dump' su lynx – JoelFan

1

So che la domanda è su PHP, ma ho usato l'idea lynx per rendere questa subroutine Perl per convertire HTML in testo:

use File::Temp; 

sub html2Txt { 
    my $html = shift; 
    my $htmlF = File::Temp->new(SUFFIX => '.html'); 
    print $htmlF $html; 
    close $htmlF; 
    return scalar `/usr/bin/lynx -dump $htmlF 2> /dev/null`; 
} 

print html2Txt '<b>Hi there</b> Testing'; 

stampe: Hi there Testing

2

si può usare lynx con -stdin e opzioni -dump per ottenere che:

<?php 
$descriptorspec = array(
    0 => array("pipe", "r"), // stdin is a pipe that the child will read from 
    1 => array("pipe", "w"), // stdout is a pipe that the child will write to 
    2 => array("file", "/tmp/htmp2txt.log", "a") // stderr is a file to write to 
); 

$process = proc_open('lynx -stdin -dump 2>&1', $descriptorspec, $pipes, '/tmp', NULL); 

if (is_resource($process)) { 
    // $pipes now looks like this: 
    // 0 => writeable handle connected to child stdin 
    // 1 => readable handle connected to child stdout 
    // Any error output will be appended to htmp2txt.log 

    $stdin = $pipes[0]; 
    fwrite($stdin, <<<'EOT' 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<title>TEST</title> 
</head> 
<body> 
<h1><span>Lorem Ipsum</span></h1> 

<h4>"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."</h4> 
<h5>"There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."</h5> 
<p> 
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et sapien ut erat porttitor suscipit id nec dui. Nam rhoncus mauris ac dui tristique bibendum. Aliquam molestie placerat gravida. Duis vitae tortor gravida libero semper cursus eu ut tortor. Nunc id orci orci. Suspendisse potenti. Phasellus vehicula leo sed erat rutrum sed blandit purus convallis. 
</p> 
<p> 
Aliquam feugiat, neque a tempus rhoncus, neque dolor vulputate eros, non pellentesque elit lacus ut nunc. Pellentesque vel purus libero, ultrices condimentum lorem. Nam dictum faucibus mollis. Praesent adipiscing nunc sed dui ultricies molestie. Quisque facilisis purus quis felis molestie ut accumsan felis ultricies. Curabitur euismod est id est pretium accumsan. Praesent a mi in dolor feugiat vehicula quis at elit. Mauris lacus mauris, laoreet non molestie nec, adipiscing a nulla. Nullam rutrum, libero id pellentesque tempus, erat nibh ornare dolor, id accumsan est risus at leo. In convallis felis at eros condimentum adipiscing aliquam nisi faucibus. Integer arcu ligula, porttitor in fermentum vitae, lacinia nec dui. 
</p> 
</body> 
</html> 
EOT 
    ); 
    fclose($stdin); 

    echo stream_get_contents($pipes[1]); 
    fclose($pipes[1]); 

    // It is important that you close any pipes before calling 
    // proc_close in order to avoid a deadlock 
    $return_value = proc_close($process); 

    echo "command returned $return_value\n"; 
} 
3

Utilizzando lince è un'opzione solo se si ha il permesso di eseguire gli eseguibili sul server. In questo modo, tuttavia, non è considerata una buona pratica. Inoltre, negli host sicuri il processo php è limitato a non essere in grado di generare le sessioni bash, che sono richieste per l'esecuzione di lynx.

La soluzione più completa scritta interamente in PHP che ho trovato è la classe Horde_Text_Filter_Html2text. È una parte di Horde framework.

Altre soluzioni che ho provato includono:

Se qualcuno ha ottenuto la soluzione ideale, per favore, inviare di nuovo per ulteriore riferimento!

1

in C#:

private string StripHTML(string source) 
{ 
    try 
    { 
     string result; 

     // Remove HTML Development formatting 
     // Replace line breaks with space 
     // because browsers inserts space 
     result = source.Replace("\r", " "); 
     // Replace line breaks with space 
     // because browsers inserts space 
     result = result.Replace("\n", " "); 
     // Remove step-formatting 
     result = result.Replace("\t", string.Empty); 
     // Remove repeating spaces because browsers ignore them 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
                   @"()+", " "); 

     // Remove the header (prepare first by clearing attributes) 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*head([^>])*>", "<head>", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"(<()*(/)()*head()*>)", "</head>", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(<head>).*(</head>)", string.Empty, 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // remove all scripts (prepare first by clearing attributes) 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*script([^>])*>", "<script>", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"(<()*(/)()*script()*>)", "</script>", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     //result = System.Text.RegularExpressions.Regex.Replace(result, 
     //   @"(<script>)([^(<script>\.</script>)])*(</script>)", 
     //   string.Empty, 
     //   System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"(<script>).*(</script>)", string.Empty, 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // remove all styles (prepare first by clearing attributes) 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*style([^>])*>", "<style>", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"(<()*(/)()*style()*>)", "</style>", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(<style>).*(</style>)", string.Empty, 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // insert tabs in spaces of <td> tags 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*td([^>])*>", "\t", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // insert line breaks in places of <BR> and <LI> tags 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*br()*>", "\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*li()*>", "\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // insert line paragraphs (double line breaks) in place 
     // if <P>, <DIV> and <TR> tags 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*div([^>])*>", "\r\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*tr([^>])*>", "\r\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<()*p([^>])*>", "\r\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // Remove remaining tags like <a>, links, images, 
     // comments etc - anything that's enclosed inside < > 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"<[^>]*>", string.Empty, 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // replace special characters: 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @" ", " ", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&bull;", " * ", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&lsaquo;", "<", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&rsaquo;", ">", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&trade;", "(tm)", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&frasl;", "/", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&lt;", "<", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&gt;", ">", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&copy;", "(c)", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&reg;", "(r)", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     // Remove all others. More can be added, see 
     // http://hotwired.lycos.com/webmonkey/reference/special_characters/ 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       @"&(.{2,6});", string.Empty, 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // for testing 
     //System.Text.RegularExpressions.Regex.Replace(result, 
     //  this.txtRegex.Text,string.Empty, 
     //  System.Text.RegularExpressions.RegexOptions.IgnoreCase); 

     // make line breaking consistent 
     result = result.Replace("\n", "\r"); 

     // Remove extra line breaks and tabs: 
     // replace over 2 breaks with 2 and over 4 tabs with 4. 
     // Prepare first to remove any whitespaces in between 
     // the escaped characters and remove redundant tabs in between line breaks 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(\r)()+(\r)", "\r\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(\t)()+(\t)", "\t\t", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(\t)()+(\r)", "\t\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(\r)()+(\t)", "\r\t", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     // Remove redundant tabs 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(\r)(\t)+(\r)", "\r\r", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     // Remove multiple tabs following a line break with just one tab 
     result = System.Text.RegularExpressions.Regex.Replace(result, 
       "(\r)(\t)+", "\r\t", 
       System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
     // Initial replacement target string for line breaks 
     string breaks = "\r\r\r"; 
     // Initial replacement target string for tabs 
     string tabs = "\t\t\t\t\t"; 
     for (int index = 0; index < result.Length; index++) 
     { 
      result = result.Replace(breaks, "\r\r"); 
      result = result.Replace(tabs, "\t\t\t\t"); 
      breaks = breaks + "\r"; 
      tabs = tabs + "\t"; 
     } 

     // That's it. 
     return result; 
    } 
    catch 
    { 
     MessageBox.Show("Error"); 
     return source; 
    } 
} 
Problemi correlati