Skip to content

Preserve whitespace display

JasonBarnabe edited this page Feb 21, 2012 · 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

fix_whitespace = lambda do |env|
	node = env[:node]
	return unless node.text?
	node.content = node.content.lstrip if node.previous_sibling.nil? or (!node.previous_sibling.description.nil? and node.previous_sibling.description.block?)
	node.content = node.content.rstrip if node.next_sibling.nil? or (!node.next_sibling.description.nil? and node.next_sibling.description.block?)
	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))
	# 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