Skip to content

Decouple load_rels from load_styles so @rels loads without styles.xml (#158)#178

Merged
satoryu merged 1 commit into
masterfrom
fix-158-decouple-load-rels
May 31, 2026
Merged

Decouple load_rels from load_styles so @rels loads without styles.xml (#158)#178
satoryu merged 1 commit into
masterfrom
fix-158-decouple-load-rels

Conversation

@satoryu
Copy link
Copy Markdown
Member

@satoryu satoryu commented May 31, 2026

Summary

Fixes #158. Relationships (and therefore hyperlinks) are now loaded independently of styles, so a document without word/styles.xml no longer leaves @rels uninitialized.

The bug

load_rels was called from inside load_styles:

def load_styles
  @styles_xml = @zip.read('word/styles.xml')   # raises Errno::ENOENT if missing
  @styles = Nokogiri::XML(@styles_xml)
  load_rels                                     # never reached when styles.xml is absent
rescue Errno::ENOENT => e
  warn e.message
  nil
end

When a document had no word/styles.xml, the @zip.read raised Errno::ENOENT, the rescue swallowed it, and load_rels never ran. @rels stayed nil, so any later call to #hyperlinks crashed:

undefined method 'xpath' for nil   # document.rb, #hyperlink_relationships

The fix

  • load_rels is now called directly from initialize, independently of load_styles.
  • load_rels also rescues a missing rels file gracefully (same pattern as load_styles), preserving the previous "swallow and warn" behavior for documents that genuinely have no rels.

Tests

  • New fixture spec/fixtures/no_styles_with_hyperlink.docx — a document that has a hyperlink relationship but no word/styles.xml (derived from formatting.docx with word/styles.xml removed).
  • New spec asserts #hyperlinks does not raise and returns {"rId4" => "http://www.google.com/"} for that document.
  • Confirmed the spec fails on master (NoMethodError) and passes with this change. Full suite green locally (146 examples, 0 failures).

Closes #158

🤖 Generated with Claude Code

Previously load_rels was called from inside load_styles, so when a document
had no word/styles.xml, load_styles raised Errno::ENOENT, was rescued, and
load_rels never ran -- leaving @RELS nil. Any later call to #hyperlinks then
crashed with "undefined method 'xpath' for nil".

load_rels is now called independently from initialize and handles a missing
rels file gracefully, so relationships load regardless of whether styles.xml
is present.

Adds a regression fixture (no_styles_with_hyperlink.docx: a document with a
hyperlink relationship but no styles.xml) and a spec asserting #hyperlinks
works in that case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@satoryu satoryu merged commit a9b6a62 into master May 31, 2026
6 checks passed
@satoryu satoryu deleted the fix-158-decouple-load-rels branch May 31, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decouple load rels method from load styles so that @rels variable can be initialized

1 participant