Во-первых, для обработки пространства я использовал хак в лямбда-вызове.
Кроме того, я использую функцию add_previous_sibling , предоставленную nokogiri, для добавления чего-либо при запуске. Наконец, Prawn не обрабатывает пробел, когда мы имеем дело с тегами ul & ol, поэтому я использовал этот gsub gsub (/ ^ ([^ \ S \ r \ n] +) / m) {| m | "\ xC2 \ xA0" * m.size} . Вы можете прочитать больше по этой ссылке
Примечание : Nokogiri не обрабатывает недопустимый HTML, поэтому всегда предоставляйте действительный HTML
RULES = {
ol: {
1 => ->(index) { "#{index + 1}. " },
2 => ->(index) { "#{}" },
3 => ->(index) { "#{}" },
4 => ->(index) { "#{}" }
},
ul: {
1 => ->(_) { "\u2022 " },
2 => ->(_) { "" },
3 => ->(_) { "" },
4 => ->(_) { "" },
},
space: {
1 => ->(index) { " " },
2 => ->(index) { " " },
3 => ->(index) { " " },
4 => ->(index) { " " },
}
}
def ol_rule(group, deepness: 1)
group.search('> li').each_with_index do |item, i|
prefix = RULES[:ol][deepness].call(i)
space = RULES[:space][deepness].call(i)
item.add_previous_sibling(space)
item.prepend_child(prefix)
descend(item, deepness + 1)
end
end
def ul_rule(group, deepness: 1)
group.search('> li').each_with_index do |item, i|
space = RULES[:space][deepness].call(i)
prefix = RULES[:ul][deepness].call(i)
item.add_previous_sibling(space)
item.prepend_child(prefix)
descend(item, deepness + 1)
end
end
def descend(item, deepness)
item.search('> ol').each do |ol|
ol_rule(ol, deepness: deepness)
end
item.search('> ul').each do |ul|
ul_rule(ul, deepness: deepness)
end
end
doc = Nokogiri::HTML.parse(text)
doc.search('ol').each do |group|
ol_rule(group, deepness: 1)
end
doc.search('ul').each do |group|
ul_rule(group, deepness: 1)
end
Prawn::Document.generate("hello.pdf") do
#puts doc.inner_text
text doc.at('body').children.to_html.gsub(/^([^\S\r\n]+)/m) { |m| "\xC2\xA0" * m.size }.gsub("<ul>","").gsub("<\/ul>","").gsub("<ol>","").gsub("<\/ol>","").gsub("<li>", "").gsub("</li>","").gsub("\\n","").gsub(/[\n]+/, "\n")
end