-
Notifications
You must be signed in to change notification settings - Fork 142
Preserve whitespace display
Jason Barnabe edited this page Jun 26, 2014
·
2 revisions
This transformer turns whitespace in posted content into <br>
s, taking into account that some whitespace (such as those between block elements) should not receive that treatment.
def replace_text_with_node(node, text, node_to_insert)
original_content = node.text
start = node.text.index(text)
# the stuff before stays in the current node
node.content = original_content[0, start]
# add the new node
node.add_next_sibling(node_to_insert)
# the stuff after becomes a new text node
node_to_insert.add_next_sibling(Nokogiri::XML::Text.new(original_content[start + text.size, original_content.size], node.document))
return [node, node.next_sibling, node.next_sibling.next_sibling]
end
def has_ancestor(node, ancestor_node_name)
until node.nil?
return true if node.name == ancestor_node_name
node = node.parent
end
return false
end
def element_is_block(node)
return false if node.nil?
# https://github.com/rgrove/sanitize/issues/108
d = Nokogiri::HTML::ElementDescription[node.name]
return !d.nil? && d.block?
end
fix_whitespace = lambda do |env|
node = env[:node]
return unless node.text?
return if has_ancestor(node, 'pre')
node.content = node.content.lstrip if element_is_block(node.previous_sibling)
node.content = node.content.rstrip if element_is_block(node.next_sibling)
return if node.text.empty?
return unless node.text.include?("\n")
resulting_nodes = replace_text_with_node(node, "\n", Nokogiri::XML::Node.new('br', node.document))
# not required in Sanitize 3
# sanitize the new nodes ourselves; they won't be picked up otherwise.
# resulting_nodes.delete(node)
# resulting_nodes.each do |new_node|
# Sanitize.clean_node!(new_node, env[:config])
# end
end