diff --git a/lib/docx/document.rb b/lib/docx/document.rb index bd2d659..498360d 100755 --- a/lib/docx/document.rb +++ b/lib/docx/document.rb @@ -40,6 +40,7 @@ def initialize(path_or_io, options = {}) @document_xml = document.get_input_stream.read @doc = Nokogiri::XML(@document_xml) load_styles + load_rels load_headers load_footers yield(self) if block_given? @@ -226,18 +227,22 @@ def load_footers def load_styles @styles_xml = @zip.read('word/styles.xml') @styles = Nokogiri::XML(@styles_xml) - load_rels rescue Errno::ENOENT => e warn e.message nil end + # Loaded independently of styles so that a document without word/styles.xml + # still initializes @rels (see #158). def load_rels rels_entry = @zip.glob('word/_rels/document*.xml.rels').first raise Errno::ENOENT unless rels_entry @rels_xml = rels_entry.get_input_stream.read @rels = Nokogiri::XML(@rels_xml) + rescue Errno::ENOENT => e + warn e.message + nil end #-- diff --git a/spec/docx/document_spec.rb b/spec/docx/document_spec.rb index d6144ef..2f2d1b7 100755 --- a/spec/docx/document_spec.rb +++ b/spec/docx/document_spec.rb @@ -612,6 +612,20 @@ end end + # Regression test for #158: relationships (and therefore hyperlinks) must be + # loaded independently of styles, so a document without word/styles.xml does + # not leave @rels uninitialized. + describe 'reading relationships when styles.xml is missing' do + before do + @doc = Docx::Document.open(@fixtures_path + '/no_styles_with_hyperlink.docx') + end + + it 'still loads hyperlink relationships' do + expect { @doc.hyperlinks }.to_not raise_error + expect(@doc.hyperlinks).to eq('rId4' => 'http://www.google.com/') + end + end + describe 'replacing contents' do let(:replacement_file_path) { @fixtures_path + '/replacement.png' } let(:temp_file_path) { Tempfile.new(['docx_gem', '.docx']).path } diff --git a/spec/fixtures/no_styles_with_hyperlink.docx b/spec/fixtures/no_styles_with_hyperlink.docx new file mode 100644 index 0000000..7c42bd2 Binary files /dev/null and b/spec/fixtures/no_styles_with_hyperlink.docx differ