docx 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b2cc086dcc2bb5043cc9f20b311f1e4b02f7c9730f459c8b91e48097d8bacb5
4
- data.tar.gz: 8536619dd3cebe92112b7328cf64cdca40be898411d974037d5e9ffc02af1a08
3
+ metadata.gz: db3defcbe5cacff393d7c87a7ad93cb305a630397f90c4ae6e93c51cf0d5b6a1
4
+ data.tar.gz: 63efc745ef47ae41110937e2b4596ad49a8b8e4bb5e4557799be6efcabee369a
5
5
  SHA512:
6
- metadata.gz: 77a0ee6f32422ad64e916b98d52d685958867e574582252d4ce424fac721cee4f73b400f8960ad88c762608024bfa7a5d966bea0cd65e1daecdb4d58967da307
7
- data.tar.gz: e87937fb28f2c6f7d7777b63df9b483fde5670e98261253b91ed55fee4d737f72cc2596542ced45a80ba525a18b9ca7a1760f76440ad71ed30facdfe17fd0cc1
6
+ metadata.gz: 1b7540ec11e9067374988c91bf09c733892275d39803bf121e88025bc27233e129712a7e478167598e8c6cf805947004807ed80cddf8461bf28c602336b53d9e
7
+ data.tar.gz: abedf7373093642703701f6ac6b7e4026a4fe713ab9af6665b39fd01de58ceffac211916cec08b14e0179f5d691afac3be3d0c5b05b8fcc0e397466e0a672385
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # docx
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/docx.svg)](https://badge.fury.io/rb/docx)
4
+ [![Build Status](https://travis-ci.org/ruby-docx/docx.svg?branch=master)](https://travis-ci.org/ruby-docx/docx)
5
+ [![Gitter](https://badges.gitter.im/ruby-docx/community.svg)](https://gitter.im/ruby-docx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
6
+
3
7
  A ruby library/gem for interacting with `.docx` files. currently capabilities include reading paragraphs/bookmarks, inserting text at bookmarks, reading tables/rows/columns/cells and saving the document.
4
8
 
5
9
  ## Usage
@@ -47,6 +51,17 @@ doc.bookmarks.each_pair do |bookmark_name, bookmark_object|
47
51
  end
48
52
  ```
49
53
 
54
+ Don't have a local file but a buffer? Docx handles those to:
55
+
56
+ ```ruby
57
+ require 'docx'
58
+
59
+ # Create a Docx::Document object from a remote file
60
+ doc = Docx::Document.open(buffer)
61
+
62
+ # Everything about reading is the same as shown above
63
+ ```
64
+
50
65
  ### Rendering html
51
66
  ``` ruby
52
67
  require 'docx'
data/lib/docx/document.rb CHANGED
@@ -20,19 +20,27 @@ module Docx
20
20
  class Document
21
21
  attr_reader :xml, :doc, :zip, :styles
22
22
 
23
- def initialize(path, &block)
23
+ def initialize(path_or_io, options = {})
24
24
  @replace = {}
25
- @zip = Zip::File.open(path)
26
- @document_xml = @zip.read('word/document.xml')
27
- @doc = Nokogiri::XML(@document_xml)
28
- @styles_xml = @zip.read('word/styles.xml')
29
- @styles = Nokogiri::XML(@styles_xml)
30
- if block_given?
31
- yield self
32
- @zip.close
25
+
26
+ # if path-or_io is string && does not contain a null byte
27
+ if (path_or_io.instance_of?(String) && !/\u0000/.match?(path_or_io))
28
+ @zip = Zip::File.open(path_or_io)
29
+ else
30
+ @zip = Zip::File.open_buffer(path_or_io)
33
31
  end
34
- end
35
32
 
33
+ document = @zip.find_entry('word/document.xml')
34
+ document ||= @zip.find_entry('word/document2.xml')
35
+ raise Errno::ENOENT if document.nil?
36
+
37
+ @document_xml = document.get_input_stream.read
38
+ @doc = Nokogiri::XML(@document_xml)
39
+ load_styles
40
+ yield(self) if block_given?
41
+ ensure
42
+ @zip.close
43
+ end
36
44
 
37
45
  # This stores the current global document properties, for now
38
46
  def document_properties
@@ -41,13 +49,12 @@ module Docx
41
49
  }
42
50
  end
43
51
 
44
-
45
52
  # With no associated block, Docx::Document.open is a synonym for Docx::Document.new. If the optional code block is given, it will be passed the opened +docx+ file as an argument and the Docx::Document oject will automatically be closed when the block terminates. The values of the block will be returned from Docx::Document.open.
46
53
  # call-seq:
47
54
  # open(filepath) => file
48
55
  # open(filepath) {|file| block } => obj
49
56
  def self.open(path, &block)
50
- self.new(path, &block)
57
+ new(path, &block)
51
58
  end
52
59
 
53
60
  def paragraphs
@@ -55,11 +62,11 @@ module Docx
55
62
  end
56
63
 
57
64
  def bookmarks
58
- bkmrks_hsh = Hash.new
65
+ bkmrks_hsh = {}
59
66
  bkmrks_ary = @doc.xpath('//w:bookmarkStart').map { |b_node| parse_bookmark_from b_node }
60
67
  # auto-generated by office 2010
61
- bkmrks_ary.reject! {|b| b.name == "_GoBack" }
62
- bkmrks_ary.each {|b| bkmrks_hsh[b.name] = b }
68
+ bkmrks_ary.reject! { |b| b.name == '_GoBack' }
69
+ bkmrks_ary.each { |b| bkmrks_hsh[b.name] = b }
63
70
  bkmrks_hsh
64
71
  end
65
72
 
@@ -70,6 +77,8 @@ module Docx
70
77
  # Some documents have this set, others don't.
71
78
  # Values are returned as half-points, so to get points, that's why it's divided by 2.
72
79
  def font_size
80
+ return nil unless @styles
81
+
73
82
  size_tag = @styles.xpath('//w:docDefaults//w:rPrDefault//w:rPr//w:sz').first
74
83
  size_tag ? size_tag.attributes['val'].value.to_i / 2 : nil
75
84
  end
@@ -103,6 +112,7 @@ module Docx
103
112
  Zip::OutputStream.open(path) do |out|
104
113
  zip.each do |entry|
105
114
  next unless entry.file?
115
+
106
116
  out.put_next_entry(entry.name)
107
117
 
108
118
  if @replace[entry.name]
@@ -115,7 +125,28 @@ module Docx
115
125
  zip.close
116
126
  end
117
127
 
118
- alias_method :text, :to_s
128
+ # Output entire document as a StringIO object
129
+ def stream
130
+ update
131
+ stream = Zip::OutputStream.write_buffer do |out|
132
+ zip.each do |entry|
133
+ next unless entry.file?
134
+
135
+ out.put_next_entry(entry.name)
136
+
137
+ if @replace[entry.name]
138
+ out.write(@replace[entry.name])
139
+ else
140
+ out.write(zip.read(entry.name))
141
+ end
142
+ end
143
+ end
144
+
145
+ stream.rewind
146
+ stream
147
+ end
148
+
149
+ alias text to_s
119
150
 
120
151
  def replace_entry(entry_path, file_contents)
121
152
  @replace[entry_path] = file_contents
@@ -123,13 +154,21 @@ module Docx
123
154
 
124
155
  private
125
156
 
157
+ def load_styles
158
+ @styles_xml = @zip.read('word/styles.xml')
159
+ @styles = Nokogiri::XML(@styles_xml)
160
+ rescue Errno::ENOENT => e
161
+ warn e.message
162
+ nil
163
+ end
164
+
126
165
  #--
127
166
  # TODO: Flesh this out to be compatible with other files
128
167
  # TODO: Method to set flag on files that have been edited, probably by inserting something at the
129
168
  # end of methods that make edits?
130
169
  #++
131
170
  def update
132
- replace_entry "word/document.xml", doc.serialize(:save_with => 0)
171
+ replace_entry 'word/document.xml', doc.serialize(save_with: 0)
133
172
  end
134
173
 
135
174
  # generate Elements::Containers::Paragraph from paragraph XML node
@@ -5,7 +5,7 @@ module Docx
5
5
  class Bookmark
6
6
  include Element
7
7
  attr_accessor :name
8
-
8
+
9
9
  def self.tag
10
10
  'bookmarkStart'
11
11
  end
@@ -17,14 +17,14 @@ module Docx
17
17
 
18
18
  # Insert text before bookmarkStart node
19
19
  def insert_text_before(text)
20
- text_run = get_run_after
21
- text_run.text = "#{text}#{text_run.text}"
20
+ text_run = get_run_before
21
+ text_run.text = "#{text_run.text}#{text}"
22
22
  end
23
23
 
24
24
  # Insert text after bookmarkStart node
25
25
  def insert_text_after(text)
26
- text_run = get_run_before
27
- text_run.text = "#{text_run.text}#{text}"
26
+ text_run = get_run_after
27
+ text_run.text = "#{text}#{text_run.text}"
28
28
  end
29
29
 
30
30
  # insert multiple lines starting with paragraph containing bookmark node.
@@ -51,7 +51,7 @@ module Docx
51
51
 
52
52
  # Get text run immediately prior to bookmark node
53
53
  def get_run_before
54
- # at_xpath returns the first match found and preceding-sibling returns siblings in the
54
+ # at_xpath returns the first match found and preceding-sibling returns siblings in the
55
55
  # order they appear in the document not the order as they appear when moving out from
56
56
  # the starting node
57
57
  if not (r_nodes = @node.xpath("./preceding-sibling::w:r")).empty?
data/lib/docx/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Docx #:nodoc:
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Hunt
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2020-02-09 00:00:00.000000000 Z
15
+ date: 2020-03-09 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: nokogiri