diff --git a/.gitignore b/.gitignore index 78ada7e..8e9c133 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .bundle Gemfile.lock pkg/* -doc/ \ No newline at end of file +doc/ +vendor/ruby diff --git a/lib/docx/document.rb b/lib/docx/document.rb index a5722d3..38c3bba 100755 --- a/lib/docx/document.rb +++ b/lib/docx/document.rb @@ -18,7 +18,7 @@ module Docx # puts d.text # end class Document - attr_reader :xml, :doc, :zip, :styles + attr_reader :xml, :doc, :zip, :styles, :headers def initialize(path, &block) @replace = {} @@ -27,6 +27,8 @@ def initialize(path, &block) @doc = Nokogiri::XML(@document_xml) @styles_xml = @zip.read('word/styles.xml') @styles = Nokogiri::XML(@styles_xml) + @header_paths = @zip.glob('word/header*.xml').map { |h| h.name } + @headers = Hash[@header_paths.map { |h| [h, ::Nokogiri::XML(@zip.read(h))] }] if block_given? yield self @zip.close @@ -57,6 +59,7 @@ def paragraphs def bookmarks bkmrks_hsh = Hash.new bkmrks_ary = @doc.xpath('//w:bookmarkStart').map { |b_node| parse_bookmark_from b_node } + bkmrks_ary += @headers.values.map { |h| h.xpath('//w:bookmarkStart').map { |b_node| parse_bookmark_from b_node } }.flatten # auto-generated by office 2010 bkmrks_ary.reject! {|b| b.name == "_GoBack" } bkmrks_ary.each {|b| bkmrks_hsh[b.name] = b } @@ -129,6 +132,7 @@ def replace_entry(entry_path, file_contents) #++ def update replace_entry "word/document.xml", doc.serialize(:save_with => 0) + @headers.each { |path, h| replace_entry(path, h.serialize(:save_with => 0)) } end # generate Elements::Containers::Paragraph from paragraph XML node diff --git a/spec/docx/document_spec.rb b/spec/docx/document_spec.rb index d038d66..e60aefd 100755 --- a/spec/docx/document_spec.rb +++ b/spec/docx/document_spec.rb @@ -422,5 +422,36 @@ end end end + + describe 'headers' do + before do + @doc = Docx::Document.open(@fixtures_path + '/headers.docx') + end + + it 'should read the document' do + expect(@doc.headers.size).to eq(3) + end + + it 'should read bookmarks' do + expect(@doc.bookmarks.size).to eq(2) + expect(@doc.bookmarks['header_bookmark']).to_not eq(nil) + end + + it 'should be able to make changes in a header bookmark' do + @doc.bookmarks['header_bookmark'].insert_text_after('testing') + expect(@doc.headers['word/header2.xml'].to_html).to include('testing') + end + + it 'should save changes in a header bookmark' do + @doc.bookmarks['header_bookmark'].insert_text_after('testing') + expect(@doc.headers['word/header2.xml'].to_html).to include('testing') + + @new_doc_path = @fixtures_path + '/new_save.docx' + @doc.save(@new_doc_path) + @new_doc = Docx::Document.open(@new_doc_path) + expect(@doc.headers['word/header2.xml'].to_html).to include('testing') + File.exists?(@new_doc_path) if File.delete(@new_doc_path) + end + end end diff --git a/spec/fixtures/headers.docx b/spec/fixtures/headers.docx new file mode 100644 index 0000000..a7a2a7c Binary files /dev/null and b/spec/fixtures/headers.docx differ