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
        # the stuff after becomes a new text node
        node_to_insert.add_next_sibling([start + text.size, original_content.size], node.document))
        return [node, node.next_sibling, node.next_sibling.next_sibling]

def has_ancestor(node, ancestor_node_name)
    until node.nil?
        return true if == ancestor_node_name
        node = node.parent
    return false

def element_is_block(node)
    return false if node.nil?
    d = Nokogiri::HTML::ElementDescription[]
    return !d.nil? && d.block?

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",'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