docx 0.2.07 → 0.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 436e2d77b50265c75cd9be63a2957a5f71da61e5
4
+ data.tar.gz: 6b14b8f1a8ec88a2f7286777f4238da6c95748e0
5
+ SHA512:
6
+ metadata.gz: aa87a1a97fab2a49e023bae4dfe1000477ed20f7cf09df9d5f63f46caf8a8e238533f2df680684f0da3530b1031a827f7d4c54fa2520a72c153214db547b0e26
7
+ data.tar.gz: 856503643daa3f057cd4625fc8f63660748e476f71712005a841721bf392d9322430dd6d5988a3c6549ef1d7668c12de49faeacb032ffe19b2e47a5d2504292b
data/LICENSE.md CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License
2
-
3
- Copyright (c) Marcus Ortiz, http://marcusortiz.com
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License
2
+
3
+ Copyright (c) Marcus Ortiz, http://marcusortiz.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -84,6 +84,11 @@ doc.bookmarks['example_bookmark'].insert_text_after("Hello world.")
84
84
  # Insert multiple lines of text at our bookmark
85
85
  doc.bookmarks['example_bookmark_2'].insert_multiple_lines_after(['Hello', 'World', 'foo'])
86
86
 
87
+ # Remove paragraphs
88
+ doc.paragraphs.each do |p|
89
+ p.remove! if p.to_s =~ /TODO/
90
+ end
91
+
87
92
  # Save document to specified path
88
93
  doc.save('example-edited.docx')
89
94
  ```
@@ -1,4 +1,4 @@
1
- require 'docx/containers/container'
2
- require 'docx/containers/text_run'
3
- require 'docx/containers/paragraph'
4
- require 'docx/containers/table'
1
+ require 'docx/containers/container'
2
+ require 'docx/containers/text_run'
3
+ require 'docx/containers/paragraph'
4
+ require 'docx/containers/table'
@@ -14,7 +14,11 @@ module Docx
14
14
  def blank!
15
15
  @node.xpath(".//w:t").each {|t| t.content = '' }
16
16
  end
17
+
18
+ def remove!
19
+ @node.remove
20
+ end
17
21
  end
18
22
  end
19
23
  end
20
- end
24
+ end
File without changes
@@ -1,51 +1,51 @@
1
- require 'docx/containers/table_row'
2
- require 'docx/containers/table_column'
3
- require 'docx/containers/container'
4
-
5
- module Docx
6
- module Elements
7
- module Containers
8
- class Table
9
- include Container
10
- include Elements::Element
11
-
12
- def self.tag
13
- 'tbl'
14
- end
15
-
16
- def initialize(node)
17
- @node = node
18
- @properties_tag = 'tblGrid'
19
- end
20
-
21
- # Array of row
22
- def rows
23
- @node.xpath('w:tr').map {|r_node| Containers::TableRow.new(r_node) }
24
- end
25
-
26
- def row_count
27
- @node.xpath('w:tr').count
28
- end
29
-
30
- # Array of column
31
- def columns
32
- columns_containers = []
33
- (0..(column_count-1)).each do |i|
34
- columns_containers[i] = Containers::TableColumn.new @node.xpath("w:tr//w:tc[#{i+1}]")
35
- end
36
- columns_containers
37
- end
38
-
39
- def column_count
40
- @node.xpath('w:tblGrid/w:gridCol').count
41
- end
42
-
43
- # Iterate over each row within a table
44
- def each_rows
45
- rows.each { |r| yield(r) }
46
- end
47
-
48
- end
49
- end
50
- end
51
- end
1
+ require 'docx/containers/table_row'
2
+ require 'docx/containers/table_column'
3
+ require 'docx/containers/container'
4
+
5
+ module Docx
6
+ module Elements
7
+ module Containers
8
+ class Table
9
+ include Container
10
+ include Elements::Element
11
+
12
+ def self.tag
13
+ 'tbl'
14
+ end
15
+
16
+ def initialize(node)
17
+ @node = node
18
+ @properties_tag = 'tblGrid'
19
+ end
20
+
21
+ # Array of row
22
+ def rows
23
+ @node.xpath('w:tr').map {|r_node| Containers::TableRow.new(r_node) }
24
+ end
25
+
26
+ def row_count
27
+ @node.xpath('w:tr').count
28
+ end
29
+
30
+ # Array of column
31
+ def columns
32
+ columns_containers = []
33
+ (0..(column_count-1)).each do |i|
34
+ columns_containers[i] = Containers::TableColumn.new @node.xpath("w:tr//w:tc[#{i+1}]")
35
+ end
36
+ columns_containers
37
+ end
38
+
39
+ def column_count
40
+ @node.xpath('w:tblGrid/w:gridCol').count
41
+ end
42
+
43
+ # Iterate over each row within a table
44
+ def each_rows
45
+ rows.each { |r| yield(r) }
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,39 +1,39 @@
1
- require 'docx/containers/text_run'
2
- require 'docx/containers/container'
3
-
4
- module Docx
5
- module Elements
6
- module Containers
7
- class TableCell
8
- include Container
9
- include Elements::Element
10
-
11
- def self.tag
12
- 'tc'
13
- end
14
-
15
- def initialize(node)
16
- @node = node
17
- @properties_tag = 'tcPr'
18
- end
19
-
20
- # Return text of paragraph's cell
21
- def to_s
22
- paragraphs.map(&:text).join('')
23
- end
24
-
25
- # Array of paragraphs contained within cell
26
- def paragraphs
27
- @node.xpath('w:p').map {|p_node| Containers::Paragraph.new(p_node) }
28
- end
29
-
30
- # Iterate over each text run within a paragraph's cell
31
- def each_paragraph
32
- paragraphs.each { |tr| yield(tr) }
33
- end
34
-
35
- alias_method :text, :to_s
36
- end
37
- end
38
- end
39
- end
1
+ require 'docx/containers/text_run'
2
+ require 'docx/containers/container'
3
+
4
+ module Docx
5
+ module Elements
6
+ module Containers
7
+ class TableCell
8
+ include Container
9
+ include Elements::Element
10
+
11
+ def self.tag
12
+ 'tc'
13
+ end
14
+
15
+ def initialize(node)
16
+ @node = node
17
+ @properties_tag = 'tcPr'
18
+ end
19
+
20
+ # Return text of paragraph's cell
21
+ def to_s
22
+ paragraphs.map(&:text).join('')
23
+ end
24
+
25
+ # Array of paragraphs contained within cell
26
+ def paragraphs
27
+ @node.xpath('w:p').map {|p_node| Containers::Paragraph.new(p_node) }
28
+ end
29
+
30
+ # Iterate over each text run within a paragraph's cell
31
+ def each_paragraph
32
+ paragraphs.each { |tr| yield(tr) }
33
+ end
34
+
35
+ alias_method :text, :to_s
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,29 +1,29 @@
1
- require 'docx/containers/table_cell'
2
- require 'docx/containers/container'
3
-
4
- module Docx
5
- module Elements
6
- module Containers
7
- class TableColumn
8
- include Container
9
- include Elements::Element
10
-
11
- def self.tag
12
- 'w:gridCol'
13
- end
14
-
15
- def initialize(cell_nodes)
16
- @node = ''
17
- @properties_tag = ''
18
- @cells = cell_nodes.map { |c_node| Containers::TableCell.new(c_node) }
19
- end
20
-
21
- # Array of cells contained within row
22
- def cells
23
- @cells
24
- end
25
-
26
- end
27
- end
28
- end
29
- end
1
+ require 'docx/containers/table_cell'
2
+ require 'docx/containers/container'
3
+
4
+ module Docx
5
+ module Elements
6
+ module Containers
7
+ class TableColumn
8
+ include Container
9
+ include Elements::Element
10
+
11
+ def self.tag
12
+ 'w:gridCol'
13
+ end
14
+
15
+ def initialize(cell_nodes)
16
+ @node = ''
17
+ @properties_tag = ''
18
+ @cells = cell_nodes.map { |c_node| Containers::TableCell.new(c_node) }
19
+ end
20
+
21
+ # Array of cells contained within row
22
+ def cells
23
+ @cells
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,28 +1,28 @@
1
- require 'docx/containers/table_cell'
2
- require 'docx/containers/container'
3
-
4
- module Docx
5
- module Elements
6
- module Containers
7
- class TableRow
8
- include Container
9
- include Elements::Element
10
-
11
- def self.tag
12
- 'tr'
13
- end
14
-
15
- def initialize(node)
16
- @node = node
17
- @properties_tag = ''
18
- end
19
-
20
- # Array of cells contained within row
21
- def cells
22
- @node.xpath('w:tc').map {|c_node| Containers::TableCell.new(c_node) }
23
- end
24
-
25
- end
26
- end
27
- end
28
- end
1
+ require 'docx/containers/table_cell'
2
+ require 'docx/containers/container'
3
+
4
+ module Docx
5
+ module Elements
6
+ module Containers
7
+ class TableRow
8
+ include Container
9
+ include Elements::Element
10
+
11
+ def self.tag
12
+ 'tr'
13
+ end
14
+
15
+ def initialize(node)
16
+ @node = node
17
+ @properties_tag = ''
18
+ end
19
+
20
+ # Array of cells contained within row
21
+ def cells
22
+ @node.xpath('w:tc').map {|c_node| Containers::TableCell.new(c_node) }
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
File without changes
@@ -1,172 +1,172 @@
1
- unless Object.const_defined?("ActiveSupport")
2
- class Module
3
- # Provides a delegate class method to easily expose contained objects' public methods
4
- # as your own. Pass one or more methods (specified as symbols or strings)
5
- # and the name of the target object via the <tt>:to</tt> option (also a symbol
6
- # or string). At least one method and the <tt>:to</tt> option are required.
7
- #
8
- # Delegation is particularly useful with Active Record associations:
9
- #
10
- # class Greeter < ActiveRecord::Base
11
- # def hello
12
- # 'hello'
13
- # end
14
- #
15
- # def goodbye
16
- # 'goodbye'
17
- # end
18
- # end
19
- #
20
- # class Foo < ActiveRecord::Base
21
- # belongs_to :greeter
22
- # delegate :hello, to: :greeter
23
- # end
24
- #
25
- # Foo.new.hello # => "hello"
26
- # Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
27
- #
28
- # Multiple delegates to the same target are allowed:
29
- #
30
- # class Foo < ActiveRecord::Base
31
- # belongs_to :greeter
32
- # delegate :hello, :goodbye, to: :greeter
33
- # end
34
- #
35
- # Foo.new.goodbye # => "goodbye"
36
- #
37
- # Methods can be delegated to instance variables, class variables, or constants
38
- # by providing them as a symbols:
39
- #
40
- # class Foo
41
- # CONSTANT_ARRAY = [0,1,2,3]
42
- # @@class_array = [4,5,6,7]
43
- #
44
- # def initialize
45
- # @instance_array = [8,9,10,11]
46
- # end
47
- # delegate :sum, to: :CONSTANT_ARRAY
48
- # delegate :min, to: :@@class_array
49
- # delegate :max, to: :@instance_array
50
- # end
51
- #
52
- # Foo.new.sum # => 6
53
- # Foo.new.min # => 4
54
- # Foo.new.max # => 11
55
- #
56
- # It's also possible to delegate a method to the class by using +:class+:
57
- #
58
- # class Foo
59
- # def self.hello
60
- # "world"
61
- # end
62
- #
63
- # delegate :hello, to: :class
64
- # end
65
- #
66
- # Foo.new.hello # => "world"
67
- #
68
- # Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
69
- # is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
70
- # delegated to.
71
- #
72
- # Person = Struct.new(:name, :address)
73
- #
74
- # class Invoice < Struct.new(:client)
75
- # delegate :name, :address, to: :client, prefix: true
76
- # end
77
- #
78
- # john_doe = Person.new('John Doe', 'Vimmersvej 13')
79
- # invoice = Invoice.new(john_doe)
80
- # invoice.client_name # => "John Doe"
81
- # invoice.client_address # => "Vimmersvej 13"
82
- #
83
- # It is also possible to supply a custom prefix.
84
- #
85
- # class Invoice < Struct.new(:client)
86
- # delegate :name, :address, to: :client, prefix: :customer
87
- # end
88
- #
89
- # invoice = Invoice.new(john_doe)
90
- # invoice.customer_name # => 'John Doe'
91
- # invoice.customer_address # => 'Vimmersvej 13'
92
- #
93
- # If the delegate object is +nil+ an exception is raised, and that happens
94
- # no matter whether +nil+ responds to the delegated method. You can get a
95
- # +nil+ instead with the +:allow_nil+ option.
96
- #
97
- # class Foo
98
- # attr_accessor :bar
99
- # def initialize(bar = nil)
100
- # @bar = bar
101
- # end
102
- # delegate :zoo, to: :bar
103
- # end
104
- #
105
- # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
106
- #
107
- # class Foo
108
- # attr_accessor :bar
109
- # def initialize(bar = nil)
110
- # @bar = bar
111
- # end
112
- # delegate :zoo, to: :bar, allow_nil: true
113
- # end
114
- #
115
- # Foo.new.zoo # returns nil
116
- def delegate(*methods)
117
- options = methods.pop
118
- unless options.is_a?(Hash) && to = options[:to]
119
- raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
120
- end
121
-
122
- prefix, allow_nil = options.values_at(:prefix, :allow_nil)
123
-
124
- if prefix == true && to =~ /^[^a-z_]/
125
- raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
126
- end
127
-
128
- method_prefix = \
129
- if prefix
130
- "#{prefix == true ? to : prefix}_"
131
- else
132
- ''
133
- end
134
-
135
- file, line = caller.first.split(':', 2)
136
- line = line.to_i
137
-
138
- to = to.to_s
139
- to = 'self.class' if to == 'class'
140
-
141
- methods.each do |method|
142
- # Attribute writer methods only accept one argument. Makes sure []=
143
- # methods still accept two arguments.
144
- definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
145
-
146
- if allow_nil
147
- module_eval(<<-EOS, file, line - 2)
148
- def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
149
- if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
150
- #{to}.#{method}(#{definition}) # client.name(*args, &block)
151
- end # end
152
- end # end
153
- EOS
154
- else
155
- exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
156
-
157
- module_eval(<<-EOS, file, line - 1)
158
- def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
159
- #{to}.#{method}(#{definition}) # client.name(*args, &block)
160
- rescue NoMethodError # rescue NoMethodError
161
- if #{to}.nil? # if client.nil?
162
- #{exception} # # add helpful message to the exception
163
- else # else
164
- raise # raise
165
- end # end
166
- end # end
167
- EOS
168
- end
169
- end
170
- end
171
- end
1
+ unless Object.const_defined?("ActiveSupport")
2
+ class Module
3
+ # Provides a delegate class method to easily expose contained objects' public methods
4
+ # as your own. Pass one or more methods (specified as symbols or strings)
5
+ # and the name of the target object via the <tt>:to</tt> option (also a symbol
6
+ # or string). At least one method and the <tt>:to</tt> option are required.
7
+ #
8
+ # Delegation is particularly useful with Active Record associations:
9
+ #
10
+ # class Greeter < ActiveRecord::Base
11
+ # def hello
12
+ # 'hello'
13
+ # end
14
+ #
15
+ # def goodbye
16
+ # 'goodbye'
17
+ # end
18
+ # end
19
+ #
20
+ # class Foo < ActiveRecord::Base
21
+ # belongs_to :greeter
22
+ # delegate :hello, to: :greeter
23
+ # end
24
+ #
25
+ # Foo.new.hello # => "hello"
26
+ # Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
27
+ #
28
+ # Multiple delegates to the same target are allowed:
29
+ #
30
+ # class Foo < ActiveRecord::Base
31
+ # belongs_to :greeter
32
+ # delegate :hello, :goodbye, to: :greeter
33
+ # end
34
+ #
35
+ # Foo.new.goodbye # => "goodbye"
36
+ #
37
+ # Methods can be delegated to instance variables, class variables, or constants
38
+ # by providing them as a symbols:
39
+ #
40
+ # class Foo
41
+ # CONSTANT_ARRAY = [0,1,2,3]
42
+ # @@class_array = [4,5,6,7]
43
+ #
44
+ # def initialize
45
+ # @instance_array = [8,9,10,11]
46
+ # end
47
+ # delegate :sum, to: :CONSTANT_ARRAY
48
+ # delegate :min, to: :@@class_array
49
+ # delegate :max, to: :@instance_array
50
+ # end
51
+ #
52
+ # Foo.new.sum # => 6
53
+ # Foo.new.min # => 4
54
+ # Foo.new.max # => 11
55
+ #
56
+ # It's also possible to delegate a method to the class by using +:class+:
57
+ #
58
+ # class Foo
59
+ # def self.hello
60
+ # "world"
61
+ # end
62
+ #
63
+ # delegate :hello, to: :class
64
+ # end
65
+ #
66
+ # Foo.new.hello # => "world"
67
+ #
68
+ # Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
69
+ # is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
70
+ # delegated to.
71
+ #
72
+ # Person = Struct.new(:name, :address)
73
+ #
74
+ # class Invoice < Struct.new(:client)
75
+ # delegate :name, :address, to: :client, prefix: true
76
+ # end
77
+ #
78
+ # john_doe = Person.new('John Doe', 'Vimmersvej 13')
79
+ # invoice = Invoice.new(john_doe)
80
+ # invoice.client_name # => "John Doe"
81
+ # invoice.client_address # => "Vimmersvej 13"
82
+ #
83
+ # It is also possible to supply a custom prefix.
84
+ #
85
+ # class Invoice < Struct.new(:client)
86
+ # delegate :name, :address, to: :client, prefix: :customer
87
+ # end
88
+ #
89
+ # invoice = Invoice.new(john_doe)
90
+ # invoice.customer_name # => 'John Doe'
91
+ # invoice.customer_address # => 'Vimmersvej 13'
92
+ #
93
+ # If the delegate object is +nil+ an exception is raised, and that happens
94
+ # no matter whether +nil+ responds to the delegated method. You can get a
95
+ # +nil+ instead with the +:allow_nil+ option.
96
+ #
97
+ # class Foo
98
+ # attr_accessor :bar
99
+ # def initialize(bar = nil)
100
+ # @bar = bar
101
+ # end
102
+ # delegate :zoo, to: :bar
103
+ # end
104
+ #
105
+ # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
106
+ #
107
+ # class Foo
108
+ # attr_accessor :bar
109
+ # def initialize(bar = nil)
110
+ # @bar = bar
111
+ # end
112
+ # delegate :zoo, to: :bar, allow_nil: true
113
+ # end
114
+ #
115
+ # Foo.new.zoo # returns nil
116
+ def delegate(*methods)
117
+ options = methods.pop
118
+ unless options.is_a?(Hash) && to = options[:to]
119
+ raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
120
+ end
121
+
122
+ prefix, allow_nil = options.values_at(:prefix, :allow_nil)
123
+
124
+ if prefix == true && to =~ /^[^a-z_]/
125
+ raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
126
+ end
127
+
128
+ method_prefix = \
129
+ if prefix
130
+ "#{prefix == true ? to : prefix}_"
131
+ else
132
+ ''
133
+ end
134
+
135
+ file, line = caller.first.split(':', 2)
136
+ line = line.to_i
137
+
138
+ to = to.to_s
139
+ to = 'self.class' if to == 'class'
140
+
141
+ methods.each do |method|
142
+ # Attribute writer methods only accept one argument. Makes sure []=
143
+ # methods still accept two arguments.
144
+ definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
145
+
146
+ if allow_nil
147
+ module_eval(<<-EOS, file, line - 2)
148
+ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
149
+ if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
150
+ #{to}.#{method}(#{definition}) # client.name(*args, &block)
151
+ end # end
152
+ end # end
153
+ EOS
154
+ else
155
+ exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
156
+
157
+ module_eval(<<-EOS, file, line - 1)
158
+ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
159
+ #{to}.#{method}(#{definition}) # client.name(*args, &block)
160
+ rescue NoMethodError # rescue NoMethodError
161
+ if #{to}.nil? # if client.nil?
162
+ #{exception} # # add helpful message to the exception
163
+ else # else
164
+ raise # raise
165
+ end # end
166
+ end # end
167
+ EOS
168
+ end
169
+ end
170
+ end
171
+ end
172
172
  end
@@ -1,148 +1,148 @@
1
- require 'docx/containers'
2
- require 'docx/elements'
3
- require 'nokogiri'
4
- require 'zip'
5
-
6
- module Docx
7
- # The Document class wraps around a docx file and provides methods to
8
- # interface with it.
9
- #
10
- # # get a Docx::Document for a docx file in the local directory
11
- # doc = Docx::Document.open("test.docx")
12
- #
13
- # # get the text from the document
14
- # puts doc.text
15
- #
16
- # # do the same thing in a block
17
- # Docx::Document.open("test.docx") do |d|
18
- # puts d.text
19
- # end
20
- class Document
21
- attr_reader :xml, :doc, :zip, :styles
22
-
23
- def initialize(path, &block)
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
33
- end
34
- end
35
-
36
-
37
- # This stores the current global document properties, for now
38
- def document_properties
39
- {
40
- font_size: font_size
41
- }
42
- end
43
-
44
-
45
- # 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
- # call-seq:
47
- # open(filepath) => file
48
- # open(filepath) {|file| block } => obj
49
- def self.open(path, &block)
50
- self.new(path, &block)
51
- end
52
-
53
- def paragraphs
54
- @doc.xpath('//w:document//w:body//w:p').map { |p_node| parse_paragraph_from p_node }
55
- end
56
-
57
- def bookmarks
58
- bkmrks_hsh = Hash.new
59
- bkmrks_ary = @doc.xpath('//w:bookmarkStart').map { |b_node| parse_bookmark_from b_node }
60
- # auto-generated by office 2010
61
- bkmrks_ary.reject! {|b| b.name == "_GoBack" }
62
- bkmrks_ary.each {|b| bkmrks_hsh[b.name] = b }
63
- bkmrks_hsh
64
- end
65
-
66
- def tables
67
- @doc.xpath('//w:document//w:body//w:tbl').map { |t_node| parse_table_from t_node }
68
- end
69
-
70
- # Some documents have this set, others don't.
71
- # Values are returned as half-points, so to get points, that's why it's divided by 2.
72
- def font_size
73
- size_tag = @styles.xpath('//w:docDefaults//w:rPrDefault//w:rPr//w:sz').first
74
- size_tag ? size_tag.attributes['val'].value.to_i / 2 : nil
75
- end
76
-
77
- ##
78
- # *Deprecated*
79
- #
80
- # Iterates over paragraphs within document
81
- # call-seq:
82
- # each_paragraph => Enumerator
83
- def each_paragraph
84
- paragraphs.each { |p| yield(p) }
85
- end
86
-
87
- # call-seq:
88
- # to_s -> string
89
- def to_s
90
- paragraphs.map(&:to_s).join("\n")
91
- end
92
-
93
- # Output entire document as a String HTML fragment
94
- def to_html
95
- paragraphs.map(&:to_html).join('\n')
96
- end
97
-
98
- # Save document to provided path
99
- # call-seq:
100
- # save(filepath) => void
101
- def save(path)
102
- update
103
- Zip::OutputStream.open(path) do |out|
104
- zip.each do |entry|
105
- out.put_next_entry(entry.name)
106
-
107
- if @replace[entry.name]
108
- out.write(@replace[entry.name])
109
- else
110
- out.write(zip.read(entry.name))
111
- end
112
- end
113
- end
114
- zip.close
115
- end
116
-
117
- alias_method :text, :to_s
118
-
119
- def replace_entry(entry_path, file_contents)
120
- @replace[entry_path] = file_contents
121
- end
122
-
123
- private
124
-
125
- #--
126
- # TODO: Flesh this out to be compatible with other files
127
- # TODO: Method to set flag on files that have been edited, probably by inserting something at the
128
- # end of methods that make edits?
129
- #++
130
- def update
131
- replace_entry "word/document.xml", doc.serialize(:save_with => 0)
132
- end
133
-
134
- # generate Elements::Containers::Paragraph from paragraph XML node
135
- def parse_paragraph_from(p_node)
136
- Elements::Containers::Paragraph.new(p_node, document_properties)
137
- end
138
-
139
- # generate Elements::Bookmark from bookmark XML node
140
- def parse_bookmark_from(b_node)
141
- Elements::Bookmark.new(b_node)
142
- end
143
-
144
- def parse_table_from(t_node)
145
- Elements::Containers::Table.new(t_node)
146
- end
147
- end
148
- end
1
+ require 'docx/containers'
2
+ require 'docx/elements'
3
+ require 'nokogiri'
4
+ require 'zip'
5
+
6
+ module Docx
7
+ # The Document class wraps around a docx file and provides methods to
8
+ # interface with it.
9
+ #
10
+ # # get a Docx::Document for a docx file in the local directory
11
+ # doc = Docx::Document.open("test.docx")
12
+ #
13
+ # # get the text from the document
14
+ # puts doc.text
15
+ #
16
+ # # do the same thing in a block
17
+ # Docx::Document.open("test.docx") do |d|
18
+ # puts d.text
19
+ # end
20
+ class Document
21
+ attr_reader :xml, :doc, :zip, :styles
22
+
23
+ def initialize(path, &block)
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
33
+ end
34
+ end
35
+
36
+
37
+ # This stores the current global document properties, for now
38
+ def document_properties
39
+ {
40
+ font_size: font_size
41
+ }
42
+ end
43
+
44
+
45
+ # 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
+ # call-seq:
47
+ # open(filepath) => file
48
+ # open(filepath) {|file| block } => obj
49
+ def self.open(path, &block)
50
+ self.new(path, &block)
51
+ end
52
+
53
+ def paragraphs
54
+ @doc.xpath('//w:document//w:body//w:p').map { |p_node| parse_paragraph_from p_node }
55
+ end
56
+
57
+ def bookmarks
58
+ bkmrks_hsh = Hash.new
59
+ bkmrks_ary = @doc.xpath('//w:bookmarkStart').map { |b_node| parse_bookmark_from b_node }
60
+ # auto-generated by office 2010
61
+ bkmrks_ary.reject! {|b| b.name == "_GoBack" }
62
+ bkmrks_ary.each {|b| bkmrks_hsh[b.name] = b }
63
+ bkmrks_hsh
64
+ end
65
+
66
+ def tables
67
+ @doc.xpath('//w:document//w:body//w:tbl').map { |t_node| parse_table_from t_node }
68
+ end
69
+
70
+ # Some documents have this set, others don't.
71
+ # Values are returned as half-points, so to get points, that's why it's divided by 2.
72
+ def font_size
73
+ size_tag = @styles.xpath('//w:docDefaults//w:rPrDefault//w:rPr//w:sz').first
74
+ size_tag ? size_tag.attributes['val'].value.to_i / 2 : nil
75
+ end
76
+
77
+ ##
78
+ # *Deprecated*
79
+ #
80
+ # Iterates over paragraphs within document
81
+ # call-seq:
82
+ # each_paragraph => Enumerator
83
+ def each_paragraph
84
+ paragraphs.each { |p| yield(p) }
85
+ end
86
+
87
+ # call-seq:
88
+ # to_s -> string
89
+ def to_s
90
+ paragraphs.map(&:to_s).join("\n")
91
+ end
92
+
93
+ # Output entire document as a String HTML fragment
94
+ def to_html
95
+ paragraphs.map(&:to_html).join('\n')
96
+ end
97
+
98
+ # Save document to provided path
99
+ # call-seq:
100
+ # save(filepath) => void
101
+ def save(path)
102
+ update
103
+ Zip::OutputStream.open(path) do |out|
104
+ zip.each do |entry|
105
+ out.put_next_entry(entry.name)
106
+
107
+ if @replace[entry.name]
108
+ out.write(@replace[entry.name])
109
+ else
110
+ out.write(zip.read(entry.name))
111
+ end
112
+ end
113
+ end
114
+ zip.close
115
+ end
116
+
117
+ alias_method :text, :to_s
118
+
119
+ def replace_entry(entry_path, file_contents)
120
+ @replace[entry_path] = file_contents
121
+ end
122
+
123
+ private
124
+
125
+ #--
126
+ # TODO: Flesh this out to be compatible with other files
127
+ # TODO: Method to set flag on files that have been edited, probably by inserting something at the
128
+ # end of methods that make edits?
129
+ #++
130
+ def update
131
+ replace_entry "word/document.xml", doc.serialize(:save_with => 0)
132
+ end
133
+
134
+ # generate Elements::Containers::Paragraph from paragraph XML node
135
+ def parse_paragraph_from(p_node)
136
+ Elements::Containers::Paragraph.new(p_node, document_properties)
137
+ end
138
+
139
+ # generate Elements::Bookmark from bookmark XML node
140
+ def parse_bookmark_from(b_node)
141
+ Elements::Bookmark.new(b_node)
142
+ end
143
+
144
+ def parse_table_from(t_node)
145
+ Elements::Containers::Table.new(t_node)
146
+ end
147
+ end
148
+ end
@@ -1,3 +1,3 @@
1
- require 'docx/elements/bookmark'
2
- require 'docx/elements/element'
1
+ require 'docx/elements/bookmark'
2
+ require 'docx/elements/element'
3
3
  require 'docx/elements/text'
File without changes
@@ -1,17 +1,17 @@
1
- module Docx
2
- module Elements
3
- class Text
4
- include Element
5
- delegate :content, :content=, :to => :@node
6
-
7
- def self.tag
8
- 't'
9
- end
10
-
11
-
12
- def initialize(node)
13
- @node = node
14
- end
15
- end
16
- end
1
+ module Docx
2
+ module Elements
3
+ class Text
4
+ include Element
5
+ delegate :content, :content=, :to => :@node
6
+
7
+ def self.tag
8
+ 't'
9
+ end
10
+
11
+
12
+ def initialize(node)
13
+ @node = node
14
+ end
15
+ end
16
+ end
17
17
  end
@@ -1,3 +1,3 @@
1
1
  module Docx #:nodoc:
2
- VERSION = '0.2.07'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.07
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Christopher Hunt
@@ -13,65 +12,88 @@ authors:
13
12
  autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
- date: 2014-10-29 00:00:00.000000000 Z
15
+ date: 2018-04-02 00:00:00.000000000 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
18
  name: nokogiri
20
19
  requirement: !ruby/object:Gem::Requirement
21
- none: false
22
20
  requirements:
23
- - - ~>
21
+ - - "~>"
24
22
  - !ruby/object:Gem::Version
25
- version: '1.5'
23
+ version: '1.8'
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.8.1
26
27
  type: :runtime
27
28
  prerelease: false
28
29
  version_requirements: !ruby/object:Gem::Requirement
29
- none: false
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ - - ">="
32
35
  - !ruby/object:Gem::Version
33
- version: '1.5'
36
+ version: 1.8.1
34
37
  - !ruby/object:Gem::Dependency
35
38
  name: rubyzip
36
39
  requirement: !ruby/object:Gem::Requirement
37
- none: false
38
40
  requirements:
39
- - - ~>
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.2'
44
+ - - ">="
40
45
  - !ruby/object:Gem::Version
41
- version: 1.1.6
46
+ version: 1.2.1
42
47
  type: :runtime
43
48
  prerelease: false
44
49
  version_requirements: !ruby/object:Gem::Requirement
45
- none: false
46
50
  requirements:
47
- - - ~>
51
+ - - "~>"
48
52
  - !ruby/object:Gem::Version
49
- version: 1.1.6
53
+ version: '1.2'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 1.2.1
50
57
  - !ruby/object:Gem::Dependency
51
58
  name: rspec
52
59
  requirement: !ruby/object:Gem::Requirement
53
- none: false
54
60
  requirements:
55
- - - ! '>='
61
+ - - "~>"
56
62
  - !ruby/object:Gem::Version
57
- version: '0'
63
+ version: '3.7'
58
64
  type: :development
59
65
  prerelease: false
60
66
  version_requirements: !ruby/object:Gem::Requirement
61
- none: false
62
67
  requirements:
63
- - - ! '>='
68
+ - - "~>"
64
69
  - !ruby/object:Gem::Version
65
- version: '0'
66
- description: a ruby library/gem for interacting with .docx files
70
+ version: '3.7'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rake
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '12.3'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '12.3'
85
+ description: thin wrapper around rubyzip and nokogiri as a way to get started with
86
+ docx files
67
87
  email:
68
88
  - chrahunt@gmail.com
69
89
  executables: []
70
90
  extensions: []
71
91
  extra_rdoc_files: []
72
92
  files:
73
- - README.md
74
93
  - LICENSE.md
94
+ - README.md
95
+ - lib/docx.rb
96
+ - lib/docx/containers.rb
75
97
  - lib/docx/containers/container.rb
76
98
  - lib/docx/containers/paragraph.rb
77
99
  - lib/docx/containers/table.rb
@@ -79,38 +101,35 @@ files:
79
101
  - lib/docx/containers/table_column.rb
80
102
  - lib/docx/containers/table_row.rb
81
103
  - lib/docx/containers/text_run.rb
82
- - lib/docx/containers.rb
83
104
  - lib/docx/core_ext/module.rb
84
105
  - lib/docx/document.rb
106
+ - lib/docx/elements.rb
85
107
  - lib/docx/elements/bookmark.rb
86
108
  - lib/docx/elements/element.rb
87
109
  - lib/docx/elements/text.rb
88
- - lib/docx/elements.rb
89
110
  - lib/docx/version.rb
90
- - lib/docx.rb
91
111
  homepage: https://github.com/chrahunt/docx
92
- licenses: []
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
93
115
  post_install_message:
94
116
  rdoc_options: []
95
117
  require_paths:
96
118
  - lib
97
119
  required_ruby_version: !ruby/object:Gem::Requirement
98
- none: false
99
120
  requirements:
100
- - - ! '>='
121
+ - - ">="
101
122
  - !ruby/object:Gem::Version
102
123
  version: '0'
103
124
  required_rubygems_version: !ruby/object:Gem::Requirement
104
- none: false
105
125
  requirements:
106
- - - ! '>='
126
+ - - ">="
107
127
  - !ruby/object:Gem::Version
108
128
  version: '0'
109
129
  requirements: []
110
130
  rubyforge_project:
111
- rubygems_version: 1.8.28
131
+ rubygems_version: 2.6.14
112
132
  signing_key:
113
- specification_version: 3
133
+ specification_version: 4
114
134
  summary: a ruby library/gem for interacting with .docx files
115
135
  test_files: []
116
- has_rdoc: