docx 0.2.07 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: