我需要将HTML转换为等效的Markdown结构文本。

OBS:: Quick and clear way of doing this with PHP & Python

当我使用PHP进行编程时,有人指出 Markdownify 可以完成这项工作,但是不幸的是,代码没有更新,实际上不能正常工作。在sourceforge.net/projects/markdownify上有一个“注释:不支持-您要维护此项目吗?请与我联系!Markdownify是用PHP编写的HTML到Markdown转换器。将其视为html2text.php的后继者更好的设计,更好的性能和更少的角落情况。”

据我发现,我只有两个不错的选择:

  • Python:亚伦·斯沃兹(Aaron Swartz)的html2text.py
  • Ruby:Singpolyma的html2markdown.rb,基于Nokogiri

  • 因此,从PHP,我需要传递HTML代码,调用Ruby/Python脚本并接收返回的输出。

    (顺便说一句,一个人在这里提出了类似的问题(“如何从php调用ruby脚本?”),但我的案例没有任何实际信息)。

    遵循Tin Man的技巧(波纹管),我明白了这一点:

    PHP代码:
    $t='<p><b>Hello</b><i>world!</i></p>';
    $scaped=preg_quote($t,"/");
    $program='python html2md.py';
    
    //exec($program.' '.$scaped,$n); print_r($n); exit; //Works!!!
    
    $input=$t;
    
    $descriptorspec=array(
       array('pipe','r'),//stdin is a pipe that the child will read from
       array('pipe','w'),//stdout is a pipe that the child will write to
       array('file','./error-output.txt','a')//stderr is a file to write to
    );
    
    $process=proc_open($program,$descriptorspec,$pipes);
    
    if(is_resource($process)){
        fwrite($pipes[0],$input);
        fclose($pipes[0]);
        $r=stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $return_value=proc_close($process);
        echo "command returned $return_value\n";
        print_r($pipes);
        print_r($r);
    }
    

    Python代码:
    #! /usr/bin/env python
    import html2text
    import sys
    print html2text.html2text(sys.argv[1])
    #print "Hi!" #works!!!
    

    有了以上,我得到这个:

    命令返回1
    大批
    (
    [0] =>资源ID#17
    1 =>资源ID#18
    )

    并且“error-output.txt”文件显示:

    追溯(最近一次通话):
    文件“html2md.py”,第5行,在
    打印html2text.html2text(sys.argv 1)
    IndexError:列表索引超出范围

    有任何想法吗???

    Ruby代码(仍在分析)
    #!/usr/bin/env ruby
    require_relative 'html2markdown'
    puts HTML2Markdown.new("<h1>#{ ARGF.read }</h1>").to_s
    

    仅作记录,我曾尝试使用PHP最简单的“exec()”,但对于HTML语言非常常见的一些特殊字符,我遇到了一些问题。

    PHP代码:
    echo exec('./hi.rb');
    echo exec('./hi.py');
    

    Ruby代码:
    #!/usr/bin/ruby
    puts "Hello World!"
    

    Python代码:
    #!usr/bin/python
    import sys
    print sys.argv[1]
    

    两者都工作正常。但是当字符串有点复杂时:
    $h='<p><b>Hello</b><i>world!</i></p>';
    echo exec("python hi.py $h");
    

    它根本不起作用。

    这是因为html字符串需要转义其特殊字符。我用这个得到的:
    $t='<p><b>Hello</b><i>world!</i></p>';
    $scaped=preg_quote($t,"/");
    

    现在它就像我说的here一样工作。

    我是runnig:
    浅顶软呢帽14
    ruby 1.8.7
    Python 2.7
    perl 5.12.2
    PHP 5.3.4
    nginx 0.8.53

    最佳答案

    让PHP通过 proc_open 打开Ruby或Python脚本,将HTML传递到脚本中的STDIN中。 Ruby/Python脚本读取和处理数据,并通过STDOUT将其返回给PHP脚本,然后退出。这是在Perl,Ruby或Python中通过类似于popen的功能来执行操作的一种常用方法,它很不错,因为它可以让您访问STDERR(以防万一,不需要大块文件并且不需要临时文件),但是它有点复杂。

    替代方法是将数据从PHP写入临时文件,然后使用 system exec 或类似的调用Ruby/Python脚本来打开和处理它,并使用其STDOUT打印输出。

    编辑:

    有关“在Ruby中使用STDIN的最佳实践?”,请参见@Jonke's answer。有关使用Ruby读取STDIN和写入STDOUT有多简单的示例。 “How do you read from stdin in python”提供了该语言的一些很好的示例。

    这是一个简单的示例,显示了如何调用Ruby脚本,如何通过PHP的STDIN管道向其传递字符串以及如何读取Ruby脚本的STDOUT:

    将此保存为“test.php”:

    <?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", "./error-output.txt", "a") // stderr is a file to write to
    );
    $process = proc_open('ruby ./test.rb', $descriptorspec, $pipes);
    
    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 /tmp/error-output.txt
    
        fwrite($pipes[0], 'hello world');
        fclose($pipes[0]);
    
        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";
    }
    ?>
    

    将此保存为“test.rb”:
    #!/usr/bin/env ruby
    
    puts "<b>#{ ARGF.read }</b>"
    

    运行PHP脚本可以得到:
    Greg:Desktop greg$ php test.php
    <b>hello world</b>
    command returned 0
    

    PHP脚本正在打开Ruby解释器,该解释器将打开Ruby脚本。然后,PHP向其发送“hello world”。 Ruby将接收到的文本用粗体标签包装,然后将其输出(由PHP捕获),然后输出。没有临时文件,没有在命令行上传递任何内容,如果需要的话,您可以传递很多数据,而且速度非常快。可以很容易地使用Python或Perl代替Ruby。

    编辑:

    如果你有:
    HTML2Markdown.new('<h1>HTMLcode</h1>').to_s
    

    作为示例代码,那么您可以开始开发具有以下内容的Ruby解决方案:
    #!/usr/bin/env ruby
    
    require_relative 'html2markdown'
    
    puts HTML2Markdown.new("<h1>#{ ARGF.read }</h1>").to_s
    

    假设您已经下载了HTML2Markdown代码并将其保存在当前目录中并且正在运行Ruby 1.9.2。

    关于php - 如何从PHP内部传递和接收参数来运行Ruby/Python脚本?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4619996/

    10-11 04:41
    查看更多