55require 'nokogiri'
66require 'zip'
77
8- # Disable ZIP64 support to maintain compatibility with the previous default behavior
9- # (before rubyzip 3.x) and ensure compatibility with all readers. Rubyzip 3.x enables
10- # ZIP64 by default, but many readers (including pandoc) don't support it for small files.
11- Zip . write_zip64_support = false
12-
138module Docx
149 # The Document class wraps around a docx file and provides methods to
1510 # interface with it.
@@ -133,40 +128,44 @@ def to_html
133128 # call-seq:
134129 # save(filepath) => void
135130 def save ( path )
136- update
137- Zip ::OutputStream . open ( path ) do |out |
138- zip . each do |entry |
139- next unless entry . file?
131+ with_zip64_disabled do
132+ update
133+ Zip ::OutputStream . open ( path ) do |out |
134+ zip . each do |entry |
135+ next unless entry . file?
140136
141- out . put_next_entry ( entry . name )
142- value = @replace [ entry . name ] || zip . read ( entry . name )
137+ out . put_next_entry ( entry . name )
138+ value = @replace [ entry . name ] || zip . read ( entry . name )
143139
144- out . write ( value )
145- end
140+ out . write ( value )
141+ end
146142
143+ end
144+ zip . close
147145 end
148- zip . close
149146 end
150147
151148 # Output entire document as a StringIO object
152149 def stream
153- update
154- stream = Zip ::OutputStream . write_buffer do |out |
155- zip . each do |entry |
156- next unless entry . file?
157-
158- out . put_next_entry ( entry . name )
159-
160- if @replace [ entry . name ]
161- out . write ( @replace [ entry . name ] )
162- else
163- out . write ( zip . read ( entry . name ) )
150+ with_zip64_disabled do
151+ update
152+ stream = Zip ::OutputStream . write_buffer do |out |
153+ zip . each do |entry |
154+ next unless entry . file?
155+
156+ out . put_next_entry ( entry . name )
157+
158+ if @replace [ entry . name ]
159+ out . write ( @replace [ entry . name ] )
160+ else
161+ out . write ( zip . read ( entry . name ) )
162+ end
164163 end
165164 end
166- end
167165
168- stream . rewind
169- stream
166+ stream . rewind
167+ stream
168+ end
170169 end
171170
172171 alias text to_s
@@ -189,6 +188,18 @@ def styles_configuration
189188
190189 private
191190
191+ # rubyzip 3.x enables ZIP64 by default, which breaks readers (e.g. pandoc)
192+ # that don't support it for small files (issue #168). Disable ZIP64 only
193+ # while writing, and restore the previous global value afterwards so we
194+ # don't affect other rubyzip users in the consuming application.
195+ def with_zip64_disabled
196+ previous = Zip . write_zip64_support
197+ Zip . write_zip64_support = false
198+ yield
199+ ensure
200+ Zip . write_zip64_support = previous
201+ end
202+
192203 def load_styles
193204 @styles_xml = @zip . read ( 'word/styles.xml' )
194205 @styles = Nokogiri ::XML ( @styles_xml )
0 commit comments