diff options
author | Sam Stephenson <sam@37signals.com> | 2018-02-07 18:26:19 -0600 |
---|---|---|
committer | Sam Stephenson <sam@37signals.com> | 2018-02-07 18:26:19 -0600 |
commit | 68d350ddacedf604717f0d1074d7624fa57757c2 (patch) | |
tree | a01852130448e37368ed2fd4af7e930e6c2cd0f2 /lib/active_text/plain_text_conversion.rb | |
parent | e22ba227a694b8426e69dbce640c5b0e4f39f574 (diff) | |
download | rails-68d350ddacedf604717f0d1074d7624fa57757c2.tar.gz rails-68d350ddacedf604717f0d1074d7624fa57757c2.tar.bz2 rails-68d350ddacedf604717f0d1074d7624fa57757c2.zip |
Initial import from BC3 RichText
Diffstat (limited to 'lib/active_text/plain_text_conversion.rb')
-rw-r--r-- | lib/active_text/plain_text_conversion.rb | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/active_text/plain_text_conversion.rb b/lib/active_text/plain_text_conversion.rb new file mode 100644 index 0000000000..3e5f3b8654 --- /dev/null +++ b/lib/active_text/plain_text_conversion.rb @@ -0,0 +1,79 @@ +module ActiveText + module PlainTextConversion + extend self + + def node_to_plain_text(node) + remove_trailing_newlines(plain_text_for_node(node)) + end + + private + def plain_text_for_node(node, index = 0) + if respond_to?(plain_text_method_for_node(node), true) + send(plain_text_method_for_node(node), node, index) + else + plain_text_for_node_children(node) + end + end + + def plain_text_for_node_children(node) + node.children.each_with_index.map do |node, index| + plain_text_for_node(node, index) + end.compact.join("") + end + + def plain_text_method_for_node(node) + :"plain_text_for_#{node.name}_node" + end + + def plain_text_for_block(node, index = 0) + "#{remove_trailing_newlines(plain_text_for_node_children(node))}\n\n" + end + + %i[ p ul ol ].each do |element| + alias_method :"plain_text_for_#{element}_node", :plain_text_for_block + end + + def plain_text_for_br_node(node, index) + "\n" + end + + def plain_text_for_text_node(node, index) + remove_trailing_newlines(node.text) + end + + def plain_text_for_div_node(node, index) + "#{remove_trailing_newlines(plain_text_for_node_children(node))}\n" + end + + def plain_text_for_figcaption_node(node, index) + "[#{remove_trailing_newlines(plain_text_for_node_children(node))}]" + end + + def plain_text_for_blockquote_node(node, index) + text = plain_text_for_block(node) + text.sub(/\A(\s*)(.+?)(\s*)\Z/m, '\1“\2”\3') + end + + def plain_text_for_li_node(node, index) + bullet = bullet_for_li_node(node, index) + text = remove_trailing_newlines(plain_text_for_node_children(node)) + "#{bullet} #{text}\n" + end + + def remove_trailing_newlines(text) + text.chomp("") + end + + def bullet_for_li_node(node, index) + if list_node_name_for_li_node(node) == "ol" + "#{index + 1}." + else + "•" + end + end + + def list_node_name_for_li_node(node) + node.ancestors.lazy.map(&:name).grep(/^[uo]l$/).first + end + end +end |