Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions lib/docx/newline_replacer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,39 @@ def walk(node)

def replace_text_node_or_continue_walking(node, child)
if child.node_type == :text
replace_text_node(node, child)
if (node.node_type == :element && node.expanded_name == 'w:t') && child.to_s.include?("\n")
replace_text_node(node, child)
end
else
walk(child)
end
end

def replace_text_node(parent, node)
grand_parent = parent.parent
list_of_new_nodes(node).reverse.each do |new_node|
parent.insert_after(node, new_node)
grand_parent.insert_after(parent, new_node)
end
node.remove
parent.remove
end

def line_break_node
br = REXML::Element.new('w:br')
REXML::Element.new('w:br')
end

def list_of_new_nodes(node)
node.to_s.split("\n")
.map{|str| str_to_text_node(str)}
.flat_map{ |txt| [txt, line_break_node] }[0..-2]
.flat_map{ |txt_node| [txt_node, line_break_node] }[0..-2]
end

def str_to_text_node(str)
respect_whitespace = true
parent = nil
raw_text = true
REXML::Text.new(str, respect_whitespace, parent, raw_text)
t = REXML::Element.new('w:t')
text = REXML::Text.new(str, respect_whitespace, parent, raw_text)
t.add_text text
end
end
end
4 changes: 2 additions & 2 deletions spec/functional/newline_conversion_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
let(:options){ {convert_newlines: true} }
it "can convert newlines with docx equivalents" do
body.should_not include("||quotes||")
body.should include("<w:t>Be excellent to eachother ~Bill and Ted<w:br/>Typing is not the bottlneck<w:br/>Do something awesome.</w:t>")
body.should include("<w:t>Be excellent to eachother ~Bill and Ted</w:t><w:br/><w:t>Typing is not the bottlneck</w:t><w:br/><w:t>Do something awesome.</w:t>")
end

it "does not double escape special characters" do
Expand All @@ -37,7 +37,7 @@
context "default" do
let(:options){ {} }
it "converts newlines" do
body.should include("Bill and Ted<w:br/>Typing")
body.should include("Bill and Ted</w:t><w:br/><w:t>Typing")
end
end
end
Expand Down
15 changes: 10 additions & 5 deletions spec/lib/docx/newline_replacer_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
require 'spec_helper'
require 'spec_helper'

describe Docx::NewlineReplacer do
let(:xml_str){ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:hdr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:t>Leslie\nKnope</w:t></w:hdr>" }
let(:xml_str){ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:hdr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:t>Leslie\nKnope</w:t><w:pict>\n </w:pict></w:hdr>" }
let(:xml_doc){ REXML::Document.new(xml_str) }
let(:replacer){ Docx::NewlineReplacer.new(xml_doc) }

it "it replaces \\n with <w:br/>" do
it "it replaces \\n with <w:br/> in text nodes" do
replacer.replace
xml_doc.to_s.should include("<w:t>Leslie</w:t><w:br/><w:t>Knope</w:t>")
end

it "it does not replace \\n with <w:br/> in not text nodes" do
replacer.replace
xml_doc.to_s.should include("<w:t>Leslie<w:br/>Knope</w:t>")
xml_doc.to_s.should include("<w:pict>\n </w:pict>")
end

context "multiple newlines" do
Expand All @@ -16,8 +22,7 @@
it "replaces all newlines in a single node" do
replacer.replace
str = xml_doc.to_s
str.should include("Leslie<w:br/>Knope")
str.should include("Ben<w:br/>Wyatt")
str.should include("<w:t>Leslie</w:t><w:br/><w:t>Knope</w:t><w:br/><w:t>loves</w:t><w:br/><w:t>Ben</w:t><w:br/><w:t>Wyatt</w:t>")
end
end
end