docxi 0.0.1

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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +119 -0
  4. data/Rakefile +10 -0
  5. data/lib/docxer.rb +29 -0
  6. data/lib/docxer/content_types.rb +68 -0
  7. data/lib/docxer/content_types/default.rb +18 -0
  8. data/lib/docxer/content_types/override.rb +18 -0
  9. data/lib/docxer/document.rb +36 -0
  10. data/lib/docxer/properties.rb +29 -0
  11. data/lib/docxer/properties/app.rb +37 -0
  12. data/lib/docxer/properties/core.rb +32 -0
  13. data/lib/docxer/relationships.rb +49 -0
  14. data/lib/docxer/relationships/relationship.rb +19 -0
  15. data/lib/docxer/version.rb +3 -0
  16. data/lib/docxer/word.rb +16 -0
  17. data/lib/docxer/word/contents.rb +6 -0
  18. data/lib/docxer/word/contents/break.rb +33 -0
  19. data/lib/docxer/word/contents/image.rb +38 -0
  20. data/lib/docxer/word/contents/paragraph.rb +59 -0
  21. data/lib/docxer/word/contents/table.rb +223 -0
  22. data/lib/docxer/word/contents/table_of_content.rb +75 -0
  23. data/lib/docxer/word/contents/text.rb +34 -0
  24. data/lib/docxer/word/document.rb +144 -0
  25. data/lib/docxer/word/effects.rb +210 -0
  26. data/lib/docxer/word/endnotes.rb +39 -0
  27. data/lib/docxer/word/fonts.rb +42 -0
  28. data/lib/docxer/word/fonts/font.rb +25 -0
  29. data/lib/docxer/word/footers.rb +30 -0
  30. data/lib/docxer/word/footers/footer.rb +118 -0
  31. data/lib/docxer/word/footnotes.rb +40 -0
  32. data/lib/docxer/word/headers.rb +30 -0
  33. data/lib/docxer/word/headers/header.rb +142 -0
  34. data/lib/docxer/word/helpers.rb +37 -0
  35. data/lib/docxer/word/medias.rb +31 -0
  36. data/lib/docxer/word/medias/media.rb +37 -0
  37. data/lib/docxer/word/numbering.rb +141 -0
  38. data/lib/docxer/word/relationships.rb +57 -0
  39. data/lib/docxer/word/relationships/relationship.rb +21 -0
  40. data/lib/docxer/word/settings.rb +61 -0
  41. data/lib/docxer/word/styles.rb +235 -0
  42. data/lib/docxer/word/themes.rb +30 -0
  43. data/lib/docxer/word/themes/theme.rb +313 -0
  44. data/lib/docxer/word/web_settings.rb +29 -0
  45. metadata +120 -0
@@ -0,0 +1,19 @@
1
+ module Docxer
2
+ class Relationships
3
+ class Relationship
4
+
5
+ attr_accessor :id, :type, :target
6
+
7
+ def initialize(id, type, target)
8
+ @id = id
9
+ @type = type
10
+ @target = target
11
+ end
12
+
13
+ def build(xml)
14
+ xml.Relationship('Id' => @id, 'Type' => @type, 'Target' => @target)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Docxer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'docxer/word/fonts'
2
+ require 'docxer/word/settings'
3
+ require 'docxer/word/styles'
4
+ require 'docxer/word/numbering'
5
+ require 'docxer/word/effects'
6
+ require 'docxer/word/web_settings'
7
+ require 'docxer/word/themes'
8
+ require 'docxer/word/medias'
9
+ require 'docxer/word/relationships'
10
+ require 'docxer/word/footnotes'
11
+ require 'docxer/word/footers'
12
+ require 'docxer/word/headers'
13
+ require 'docxer/word/endnotes'
14
+ require 'docxer/word/contents'
15
+ require 'docxer/word/helpers'
16
+ require 'docxer/word/document'
@@ -0,0 +1,6 @@
1
+ require 'docxer/word/contents/break'
2
+ require 'docxer/word/contents/text'
3
+ require 'docxer/word/contents/table_of_content'
4
+ require 'docxer/word/contents/image'
5
+ require 'docxer/word/contents/paragraph'
6
+ require 'docxer/word/contents/table'
@@ -0,0 +1,33 @@
1
+ module Docxer
2
+ module Word
3
+ module Contents
4
+
5
+ class Break
6
+
7
+ attr_accessor :options
8
+ def initialize(options={})
9
+ @options = options
10
+ @options[:times] ||= 1
11
+ end
12
+
13
+ def render(xml)
14
+ if @options[:page]
15
+ xml['w'].p do
16
+ xml['w'].r do
17
+ xml['w'].br( 'w:type' => "page" )
18
+ end
19
+ end
20
+ else
21
+ @options[:times].times do
22
+ xml['w'].r do
23
+ xml['w'].br
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ module Docxer
2
+ module Word
3
+ module Contents
4
+
5
+ class Image
6
+
7
+ attr_accessor :media, :options
8
+ def initialize(media, options={})
9
+ @media = media
10
+ @media.file.rewind
11
+ @options = options
12
+ end
13
+
14
+ def styles
15
+ if @options[:style]
16
+ @options[:style].collect{|k, v| [k, v].join(':')}.join(';')
17
+ end
18
+ end
19
+
20
+ def render(xml)
21
+ xml['w'].r do
22
+ xml['w'].rPr do
23
+ xml['w'].noProof
24
+ end
25
+ xml['w'].pict do
26
+ xml['v'].shape( 'id' => @media.uniq_id, 'type' => @media.type, 'style' => styles ) do
27
+ xml['v'].imagedata( 'r:id' => @media.sequence, 'o:title' => @options[:title] )
28
+ end
29
+ end
30
+ xml['w'].rPr do
31
+ xml['w'].noProof
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,59 @@
1
+ module Docxer
2
+ module Word
3
+ module Contents
4
+
5
+ class Paragraph
6
+
7
+ attr_accessor :content, :options
8
+ def initialize(options={})
9
+ @content = []
10
+ @options = options
11
+
12
+ if block_given?
13
+ yield self
14
+ else
15
+
16
+ end
17
+ end
18
+
19
+ def render(xml)
20
+ xml['w'].p do
21
+ xml['w'].pPr do
22
+ xml['w'].jc( 'w:val' => @options[:align]) if @options[:align]
23
+ if options[:ul]
24
+ xml['w'].numPr do
25
+ xml['w'].ilvl( 'w:val' => 0 )
26
+ xml['w'].numId( 'w:val' => 1 )
27
+ end
28
+ end
29
+ end
30
+ @content.each do |element|
31
+ element.render(xml)
32
+ end
33
+ end
34
+ end
35
+
36
+ def text(text, options={})
37
+ options = @options.merge(options)
38
+ text = Docxer::Word::Contents::Text.new(text, options)
39
+ @content << text
40
+ text
41
+ end
42
+
43
+ def br(options={})
44
+ br = Docxer::Word::Contents::Break.new(options)
45
+ @content << br
46
+ br
47
+ end
48
+
49
+ def image(image, options={})
50
+ img = Docxer::Word::Contents::Image.new(image, options)
51
+ @content << img
52
+ img
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,223 @@
1
+ module Docxer
2
+ module Word
3
+ module Contents
4
+
5
+ class Table
6
+
7
+ attr_accessor :options, :rows
8
+ def initialize(options={})
9
+ @options = options
10
+ @rows = []
11
+
12
+ if block_given?
13
+ yield self
14
+ else
15
+
16
+ end
17
+ end
18
+
19
+ def tr(options={}, &block)
20
+ options = @options.merge(options)
21
+ row = TableRow.new(options, &block)
22
+ @rows << row
23
+ row
24
+ end
25
+
26
+ def render(xml)
27
+ xml['w'].tbl do
28
+ xml['w'].tblPr do
29
+ xml['w'].tblStyle( 'w:val' => options[:style] ) if options[:style]
30
+ xml['w'].tblW( 'w:w' => options[:width], 'w:type' => "auto" ) if options[:width]
31
+ xml['w'].tblLook( 'w:val' => "04A0", 'w:firstRow' => 1, 'w:lastRow' => 0, 'w:firstColumn' => 1, 'w:lastColumn' => 0, 'w:noHBand' => 0, 'w:noVBand' => 1 )
32
+ if @options[:borders]
33
+ xml['w'].tblBorders do
34
+ @options[:borders].each do |k, v|
35
+ if v.nil?
36
+ xml['w'].send(k, 'w:val' => "none", 'w:sz' => "0", 'w:space' => "0", 'w:color' => "auto" )
37
+ else
38
+ xml['w'].send(k, 'w:val' => "none", 'w:sz' => v, 'w:space' => "0", 'w:color' => "auto" )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ xml['w'].tblGrid do
45
+ if options[:columns_width]
46
+ options[:columns_width].each do |width|
47
+ xml['w'].gridCol( 'w:w' => width.to_i * 14.92 )
48
+ end
49
+ end
50
+ end
51
+ @rows.each do |row|
52
+ row.render(xml)
53
+ end
54
+ end
55
+ end
56
+
57
+ class TableRow
58
+
59
+ attr_accessor :options, :cells
60
+ def initialize(options={})
61
+ @options = options
62
+ @cells = []
63
+
64
+ if block_given?
65
+ yield self
66
+ else
67
+
68
+ end
69
+ end
70
+
71
+ def tc(options={}, &block)
72
+ if @options[:columns_width]
73
+ width = @options[:columns_width][@cells.size]
74
+ options[:width] ||= width if width
75
+ end
76
+ options = @options.merge(options)
77
+ cell = TableCell.new(options, &block)
78
+ @cells << cell
79
+ cell
80
+ end
81
+
82
+ def render(xml)
83
+ xml['w'].tr do
84
+ @cells.each do |cell|
85
+ cell.render(xml)
86
+ end
87
+ end
88
+ end
89
+
90
+ class TableCell
91
+
92
+ attr_accessor :options, :content
93
+ def initialize(options={})
94
+ @options = options
95
+ @content = []
96
+
97
+ if block_given?
98
+ yield self
99
+ else
100
+
101
+ end
102
+ end
103
+
104
+ def render(xml)
105
+ xml['w'].tc do
106
+ xml['w'].tcPr do
107
+ xml['w'].tcW( 'w:w' => ( options[:width].to_i * 14.92 ).to_i, 'w:type' => "dxa" ) if options[:width]
108
+ xml['w'].shd( 'w:val' => "clear", 'w:color' => "auto", 'w:fill' => options[:fill] ) if options[:fill]
109
+ if options[:borders]
110
+ xml['w'].tcBorders do
111
+ options[:borders].each do |k, v|
112
+ if v.nil?
113
+ xml['w'].send(k, 'w:val' => "nil" )
114
+ else
115
+ xml['w'].send(k, 'w:val' => "single", 'w:sz' => v, 'w:space' => "0", 'w:color' => "auto" )
116
+ end
117
+ end
118
+ end
119
+ end
120
+ if options[:merged]
121
+ xml['w'].vMerge
122
+ else
123
+ xml['w'].vAlign( 'w:val' => options[:valign] ) if options[:valign]
124
+ xml['w'].gridSpan( 'w:val' => options[:colspan] ) if options[:colspan]
125
+ xml['w'].vMerge( 'w:val' => "restart" ) if options[:rowspan]
126
+ end
127
+ end
128
+ if options[:merged]
129
+ xml['w'].p
130
+ else
131
+ @content.each do |element|
132
+ element.render(xml)
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ def text(text, options={})
139
+ options = @options.merge(options)
140
+ element = Docxer::Word::Contents::Paragraph.new(options) do |p|
141
+ p.text(text)
142
+ end
143
+ @content << element
144
+ element
145
+ end
146
+
147
+ def image(image, options={})
148
+ img = Image.new(image, options)
149
+ @content << img
150
+ img
151
+ end
152
+
153
+ class Image
154
+ attr_accessor :media, :options
155
+ def initialize(media, options={})
156
+ @media = media
157
+ @options = options
158
+ end
159
+
160
+ def render(xml)
161
+ xml['w'].p do
162
+ xml['w'].r do
163
+ xml['w'].rPr do
164
+ xml['w'].noProof
165
+ end
166
+ xml['w'].drawing do
167
+ xml['wp'].inline( 'distT' => 0, 'distB' => 0, 'distL' => 0, 'distR' => 0 ) do
168
+ xml['wp'].extent( 'cx' => ( options[:width] * options[:height] * 14.92 ).to_i, 'cy' => ( options[:width] * options[:height] * 14.92 ).to_i ) if options[:width] && options[:height]
169
+ xml['wp'].effectExtent( 'l' => 0, 't' => 0, 'r' => 0, 'b' => 0 )
170
+ xml['wp'].docPr( 'id' => @media.id, 'name'=> "Image", 'descr' => "image")
171
+ xml['wp'].cNvGraphicFramePr do
172
+ xml.graphicFrameLocks( 'xmlns:a' => "http://schemas.openxmlformats.org/drawingml/2006/main", 'noChangeAspect' => "1" ) do
173
+ xml.parent.namespace = xml.parent.namespace_definitions.find{|ns| ns.prefix == "a" }
174
+ end
175
+ end
176
+ xml.graphic( 'xmlns:a' => "http://schemas.openxmlformats.org/drawingml/2006/main" ) do
177
+ xml.parent.namespace = xml.parent.namespace_definitions.find{|ns| ns.prefix == "a" }
178
+ xml['a'].graphicData( 'uri' => "http://schemas.openxmlformats.org/drawingml/2006/picture") do
179
+ xml.pic( 'xmlns:pic' => "http://schemas.openxmlformats.org/drawingml/2006/picture") do
180
+ xml.parent.namespace = xml.parent.namespace_definitions.find{|ns| ns.prefix == "pic" }
181
+ xml['pic'].nvPicPr do
182
+ xml['pic'].cNvPr( 'id' => 0, 'name' => "Image", 'descr' => "description" )
183
+ xml['pic'].cNvPicPr do
184
+ xml['a'].picLocks( 'noChangeAspect' => "1", 'noChangeArrowheads' => "1" )
185
+ end
186
+ end
187
+ xml['pic'].blipFill do
188
+ xml['a'].blip( 'r:embed' => @media.sequence ) do
189
+ xml['a'].extLst
190
+ end
191
+ xml['a'].srcRect
192
+ xml['a'].stretch do
193
+ xml['a'].fillRect
194
+ end
195
+ end
196
+ xml['pic'].spPr( 'bwMode' => "auto" ) do
197
+ xml['a'].xfrm do
198
+ xml['a'].off( 'x' => 0, 'y' => 0 )
199
+ xml['a'].ext( 'cx' => ( options[:width] * options[:height] * 14.92 ).to_i, 'cy' => ( options[:width] * options[:height] * 14.92).to_i ) if options[:width] && options[:height]
200
+ end
201
+ xml['a'].prstGeom( 'prst' => "rect" ) do
202
+ xml['a'].avLst
203
+ end
204
+ xml['a'].noFill
205
+ xml['a'].ln do
206
+ xml['a'].noFill
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,75 @@
1
+ module Docxer
2
+ module Word
3
+ module Contents
4
+
5
+ class TableOfContent
6
+
7
+ attr_accessor :options, :rows
8
+ def initialize(options={})
9
+ @options = options
10
+ @rows = []
11
+
12
+ if block_given?
13
+ yield self
14
+ else
15
+
16
+ end
17
+ end
18
+
19
+ def add_row(text, page=nil, options={})
20
+ row = Row.new(text, page, options)
21
+ @rows << row
22
+ row
23
+ end
24
+
25
+ def render(xml)
26
+ @rows.each do |row|
27
+ row.render(xml)
28
+ end
29
+ end
30
+
31
+
32
+ class Row
33
+
34
+ attr_accessor :text, :page, :options
35
+ def initialize(text, page=nil, options={})
36
+ @text = text
37
+ @page = page
38
+ @options = options
39
+ end
40
+
41
+ def render(xml)
42
+ if @page.nil?
43
+ xml['w'].p do
44
+ xml['w'].pPr do
45
+ xml['w'].spacing( 'w:before' => "0", 'w:after' => "160")
46
+ end
47
+ xml['w'].r do
48
+ xml['w'].tab
49
+ xml['w'].t @text
50
+ end
51
+ end
52
+ else
53
+ xml['w'].p do
54
+ xml['w'].pPr do
55
+ xml['w'].pStyle( 'w:val' => "ListParagraph") # TODO: Apply styles
56
+ xml['w'].spacing( 'w:before' => "0", 'w:after' => "160")
57
+ xml['w'].tabs do
58
+ xml['w'].tab( 'w:val' => "right", 'w:leader' => @options[:leader] || 'dot', 'w:pos' => @options[:pos] || 9360 )
59
+ end
60
+ end
61
+ xml['w'].r do
62
+ xml['w'].t @text
63
+ end
64
+ xml['w'].r do
65
+ xml['w'].tab
66
+ xml['w'].t( @page, 'xml:space' => "preserve" )
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end