2013-10-19 94 views
3

我正在試圖製作Pod::Simple::HTML的簡單子類,以便與Pod::Simple::HTMLBatch一起使用。我希望所有的POD都可以用POD::Weaver進行預處理。但是,我無法找到用於處理Pod :: Weaver的字符串文檔的API /命令。完成我想要的基本大綱是這樣的:在使用Pod之前預處理POD :: Pod :: Weaver :: Simple :: HTML

use strict; 
use warnings; 
use Pod::Simple::HTMLBatch; 

my $batchconv = Pod::Simple::HTMLBatch->new; 
$batchconv->html_render_class('My::Pod'); 
$batchconv->batch_convert(['path/to/code'], 'path/to/output'); 

package My::Pod; 
use Pod::Weaver; 
use parent qw(Pod::Simple::HTML); 

sub parse_file { 
    my ($self, $in_file) = @_; 

    my $new_doc = 'Pod::Weaver transformed pod here' 

    return $self->SUPER::parse_string_document($new_doc); 
} 

有沒有人曾經做過類似的事情?誰能告訴我如何變換$in_file,這可能是.pm.pod文件,Pod:Weaver?

+0

看來你必須先創建一個帶有Pod :: Elemental的文檔。 –

回答

1

好吧,事實證明這比預期的要難得多,這可能是一個壞主意。我們真正需要的是將Pod :: Elemental文檔轉換爲(X)HTML(5)的新工具,兼容Pod :: Simple::(X)HTML(以便我們可以繼續使用舊的CSS樣式)。我會接受另一個答案,如果有人寫/找到一個合適的模塊併發布在這裏。

所以這就是我所做的。我不得不繼承POD::Simple::Search,因爲它使用正則表達式檢查POD文件,該正則表達式不包含與Pod :: Weaver一起使用的=method之類的內容。對於每個文件,我必須創建一個PPI文檔並去除POD,然後連接POD並將其製作爲Pod :: Elemental文檔。這就是它在Pod :: Elemental :: PerlMunger中的工作方式,這是Dist :: Zilla使用的。

package My::Pod; 
use strict; 
use warnings; 

use Pod::Weaver; 
use Pod::Elemental; 
use Software::License::Perl_5; 
use PPI; 
use List::MoreUtils qw(any); 
use parent qw(Pod::Simple::HTML); 

my $weaver = Pod::Weaver->new_with_default_config; 
my $license = Software::License::Perl_5->new({ 
    holder => 'DFKI', 
}); 

sub parse_file { 
    my ($self, $in_file) = @_; 

    my $doc = get_doc($in_file); 

    my $document = $weaver->weave_document({ 
     pod_document => $doc->{pod}, 
     ppi_document => $doc->{ppi}, 
     authors => ['Nathan Glenn <[email protected]>'], 
     license => $license, 
    }); 

    return $self->SUPER::parse_string_document($document->as_pod_string); 
} 

#return {ppi, pod} 
#Most of this taken from Pod::Elemental::PerlMunger 
sub get_doc { 
    my ($file_name) = @_; 

    my $ppi_document = PPI::Document->new($file_name); 
    confess(PPI::Document->errstr) unless $ppi_document; 

    my @pod_tokens = map {"$_"} @{ $ppi_document->find('PPI::Token::Pod') || [] }; 
    $ppi_document->prune('PPI::Token::Pod'); 

    my $finder = sub { 
     my $node = $_[1]; 
     return 0 unless any { $node->isa($_) } 
      qw(PPI::Token::Quote PPI::Token::QuoteLike PPI::Token::HereDoc); 
     return 1 if $node->content =~ /^=[a-z]/m; 
     return 0; 
    }; 

    if ($ppi_document->find_first($finder)) { 
     warn "can't get POD from $file_name: there is POD inside string literals"; 
    } 

    my $pod_str = join "\n", @pod_tokens; 
    my $pod_document = Pod::Elemental->read_string($pod_str); 

    return {ppi => $ppi_document, pod => $pod_document}; 
} 

# search package to tell Pod::Simple::HTMLBatch that everything has POD 
package My::Pod::Search; 
use parent qw(Pod::Simple::Search); 

#override this method to allow whatever kinds of POD commands (=method, etc.) 
#mostly copied from Pod::Simple::Search 
sub contains_pod { 
    my($self, $file) = @_; 
    my $verbose = $self->{'verbose'}; 

    # check for one line of POD 
    $verbose > 1 and print " Scanning $file for pod...\n"; 
    unless(open(MAYBEPOD,"<$file")) { 
     print "Error: $file is unreadable: $!\n"; 
     return undef; 
    } 


    local $_; 
    while(<MAYBEPOD>) { 
     # a more forgiving pod regex for things like =method 
     if(m/^=(.+)\b/s) { 
      close(MAYBEPOD) || die "Bizarre error closing $file: $!\nAborting"; 
      chomp; 
      $verbose > 1 and print " Found some pod ($_) in $file\n"; 
      return 1; 
     } 
    } 
    close(MAYBEPOD) || die "Bizarre error closing $file: $!\nAborting"; 
    $verbose > 1 and print " No POD in $file, skipping.\n"; 
    return 0; 
} 

package main; 

my $batchconv = Pod::Simple::HTMLBatch->new; 
$batchconv->html_render_class('My::Pod'); 
$batchconv->search_class('My::Pod::Search'); 
$batchconv->batch_convert(['path/to/code'], 'path/to/output');