2009-12-18 36 views
8

Bạn có biết bất kỳ HTML nào tốt cho lớp chuyển đổi văn bản thuần túy được viết bằng PHP không?HTML tới văn bản thuần túy (cho email)

Tôi cần nó để chuyển đổi nội dung thư HTML sang nội dung thư văn bản thuần túy.

tôi đã viết chức năng đơn giản, nhưng tôi cần các tính năng giống như bảng chuyển đổi, liên kết thêm ở cuối, chuyển đổi danh sách lồng nhau ...

- liên quan
takeshin

+0

Tại sao không chỉ cần gửi mail HTML? Tôi hiểu rằng các bảng giả mạo là có thể có trong bản rõ nhưng mọi trình đọc email trên thế giới đọc HTML, tại sao không tự khắc phục sự cố chuyển đổi vô nghĩa bởi vì bạn hoặc ai đó từ chối sử dụng thư HTML. – TravisO

+4

TravisO: Không phải mọi người đọc. Và một số không tự động chuyển đổi HTML thành văn bản thuần túy. Đối với người dùng, HTML thô thường không tốt để đọc :-) – Joey

+0

1996 kết thúc, hãy sử dụng nó.Nhưng tất nhiên những người theo chủ nghĩa ưu tú, những người ghét email HTML sẽ trở thành giọng hát nhiều nhất/sẵn sàng bỏ phiếu cho những lý tưởng đó. – TravisO

Trả lời

6

tôi muốn đề nghị sử dụng một công cụ chuyển đổi HTML sang Markdown.

+2

Và những gì tốt là đánh dấu trong một email văn bản? –

+1

Uh, bạn đã sử dụng hoặc đọc bất cứ điều gì về Markdown? "Mục tiêu thiết kế quan trọng đối với cú pháp định dạng của Markdown là làm cho nó dễ đọc nhất có thể. ** Ý tưởng là tài liệu có định dạng Markdown phải có thể xuất bản dưới dạng văn bản thuần túy, không trông giống như được đánh dấu bằng thẻ hoặc hướng dẫn định dạng. ** " – ceejayoz

+2

Markdownify là một giải pháp tốt, thực sự. Tôi đã xem nó trước đây, nhưng tôi nghĩ rằng nó không chuyển đổi bảng. Nhưng vấn đề là, tôi đã thử trên các bảng với các thuộc tính '' và một số kiểu css. Tôi đã tước phụ đề theo cách thủ công và thuộc tính lớp học và phong cách, và nó hoạt động tốt đẹp. – takeshin

3

Một đặc biệt gửi mail thực hiện quanh đây chỉ đơn giản là spawns lynx với HTML và sử dụng sản lượng của nó cho phiên bản văn bản. Nó không hoàn hảo nhưng hoạt động. Bạn cũng có thể sử dụng links hoặc elinks.

+0

Ý tưởng gọn gàng, tôi thích nó. – ceejayoz

+0

Có, điều này đã được đề xuất trên StackOverflow, nhưng tôi đã yêu cầu linh hồn PHP. Tôi không có quyền truy cập vào lynx vào máy chủ của mình. Cảm ơn. – takeshin

+0

Bạn quên đề cập đến rằng bạn cần '-dump' arg đến lynx – JoelFan

1

Tôi biết câu hỏi là về PHP, nhưng tôi đã sử dụng ý tưởng lynx để làm cho chương trình con Perl này để chuyển đổi HTML sang văn bản:

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'; 

in: Hi there Testing

2

Bạn có thể sử dụng lynx với -stdin và -dump tùy chọn để đạt được điều đó:

<?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

Sử dụng lynx là tùy chọn chỉ khi bạn có quyền chạy tệp thực thi trên máy chủ. Làm như vậy, tuy nhiên, không được coi là một thực hành tốt. Hơn nữa, trong các host an toàn, tiến trình php bị hạn chế không thể sinh ra các phiên bash, được yêu cầu để chạy lynx.

Giải pháp hoàn chỉnh nhất được viết hoàn toàn bằng PHP mà tôi có thể tìm thấy là lớp Horde_Text_Filter_Html2text. Nó là một phần từ số Horde framework.

giải pháp khác tôi đã cố gắng bao gồm:

Nếu ai đó có giải pháp hoàn hảo, làm ơn, gửi nó trở lại để tham khảo thêm!

1

Trong 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; 
    } 
} 
Các vấn đề liên quan