是否可以使用Perl脚本将HTML有序和无序列表转换为kramdown,如果该文件可能包含多种类型的列表,以及其他HTML代码?
为了说明意图,如果只有一个有序列表而没有其他列表,那么类似下面的内容可能会有效:
$content =~ s!<\/ol>!!gis;
$content =~ s!<ol>!!gis;
$content =~ s!<\/li>!!gis;
$content =~ s!<li>!1. !gis;
如果只有一个无序列表而没有其他列表,那么这可能有效:
$content =~ s!<\/ol>!!gis;
$content =~ s!<ol>!!gis;
$content =~ s!<\/li>!!gis;
$content =~ s!<li>!- !gis;
例如,是否可以在HTML文档中找到每个列表,并将其传递给子例程,该子例程将确定列表的类型,将其适当转换并返回?
答案 0 :(得分:2)
最简单的方法是使用kramdown本身,因为它可以解析HTML并发出一个kramdown文档。
使用kramdown二进制文件只需使用kramdown -i html -o kramdown INPUT.HTML
。
答案 1 :(得分:0)
通常,您不应使用正则表达式来解析HTML。相反,您应该使用像Mojo::DOM这样的HTML解析器:
use strict;
use warnings 'all';
use Mojo::DOM;
# Add the appropriate kramdown list marker to a Mojo::DOM node representing a
# single <li>, depending on whether it's in an <ol> or <ul>
sub add_list_marker {
my ($node, $i) = @_;
my $marker = $node->parent->tag eq 'ol' ? "$i. " : '- ';
$node->prepend_content($marker);
}
# Convert a Mojo::DOM node representing an <ol> or <ul> to the corresponding
# kramdown
sub list_to_kramdown {
my ($node) = @_;
my $items = $node->children('li')->each(\&add_list_marker);
my $text = $items->map('text')->join("\n");
$node->replace("\n$text\n");
}
my $html = do {
local $/;
<DATA>
};
my $dom = Mojo::DOM->new($html);
$dom->find('ol, ul')->each(\&list_to_kramdown);
print $dom->to_string;
__DATA__
<h1>Leave surrounding HTML</h1>
<div id="including_enclosing_tags">
<ol>
<li>foo</li>
<li>bar</li><li>baz</li>
<li>qux</li>
</ol>
<ul>
<li class="fruit">apple</li>
<li>pear</li>
<li>banana</li>
<li>pine
apple</li>
</ul>
</div>
输出:
<h1>Leave surrounding HTML</h1>
<div id="including_enclosing_tags">
1. foo
2. bar
3. baz
4. qux
- apple
- pear
- banana
- pine apple
</div>
这比正则表达式更好,因为它可以轻松处理:
<li>
元素<li>
元素跨越多行