caracal 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa886d1701a3fd3be57df67220f491dc020759ff
4
- data.tar.gz: 0819776425e4c055c74946f6cf9c73622b8964cd
3
+ metadata.gz: c858148d5ae537806007e2e90609ef72cb78aaad
4
+ data.tar.gz: e92af27b1c79d1842ed2aac515aedfe0452bb53c
5
5
  SHA512:
6
- metadata.gz: 01bbb4a1ea7264b9f95363005af6acaa76796a1085a6ef3264645b4cd29f586a79bddcf87d458ae69d63fefd3570908367e7982cdf1705d608d5ab15dd593482
7
- data.tar.gz: 8d116facbd2f0a0c7de17a85cf6694ffca5d8fd88799ccfd20159dbb13402f2e9ef6f57979d6982d2e462682749a93364e0323544602176396a1ce3a3a0c54c1
6
+ metadata.gz: 42047a3d1dc77994ef4bf3f733c5634e6d1dbeec590a7895e9d299a8ae93ac565a6c974b9577f87f4e612936e70ace9fc9c2b7063a42d7b858e8fc10e0724b3b
7
+ data.tar.gz: 795fde5d5a5561e750ccb90953a763b173a48a55a7179197d1eb186203d585c704ba2ed728276a25e2c56dd8d2d67961ee2d81af351655e062110f129abb9f4f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ #### v1.0.3
2
+
3
+ * Enhancements
4
+ * Added custom properties (@davidtolsma).
5
+ * Added page breaks to paragraph model sub-functions (@jdugan).
6
+
7
+
1
8
  #### v1.0.2
2
9
 
3
10
  * Enhancements
@@ -7,7 +14,7 @@
7
14
  #### v0.3.0
8
15
 
9
16
  * Deprecations
10
- * The :style attribute is no longer allowed on text and link commands. Use :font, :size, etc. instead.
17
+ * The :style attribute is no longer allowed on text and link commands. Use :font, :size, etc. instead (@jdugan).
11
18
 
12
19
 
13
20
  #### v0.2.1
@@ -22,15 +29,14 @@
22
29
  * Enhancements
23
30
  * Implemented true line breaks within paragraphs (@Linuus).
24
31
  * Converted paragraph command to accept/allow blank content (@Linuus).
25
- * Allowed :top and :bottom attributes to be set on default paragraph style (@jpdugan).
32
+ * Allowed :top and :bottom attributes to be set on default paragraph style (@jdugan).
26
33
 
27
34
 
28
35
  * Deprecations
29
- * Line breaks are no longer allowed at the document level. Use blank paragraphs instead.
30
-
36
+ * Line breaks are no longer allowed at the document level. Use blank paragraphs instead (@jdugan).
31
37
 
32
38
 
33
39
  #### v0.1.x
34
40
 
35
41
  * Enhancements
36
- * Initial commits. (@jpdugan)
42
+ * Initial commits. (@jdugan)
data/README.md CHANGED
@@ -90,6 +90,7 @@ For each Caracal request, the following document structure will be created and z
90
90
  |- docProps
91
91
  |- app.xml
92
92
  |- core.xml
93
+ |- custom.xml
93
94
  |- word
94
95
  |- _rels
95
96
  |- document.xml.rels
@@ -119,6 +120,9 @@ Specifies the name of the application that generated the document. *This file is
119
120
  **docProps/core.xml**
120
121
  Specifies the title of the document. *This file is generated automatically by the library based on other user directives.*
121
122
 
123
+ **docProps/custom.xml**
124
+ Specifies the custom document properties. *This file is generated automatically by the library based on other user directives.*
125
+
122
126
  **word/_rels/document.xml.rels**
123
127
  Defines an internal identifier and type with all external content items (images, links, etc). *This file is generated automatically by the library based on other user directives.*
124
128
 
@@ -167,14 +171,14 @@ A twip is 1/20 of a point. Word documents are printed at 72dpi. 1in == 72pt ==
167
171
  In Word documents, pixels are equivalent to points.
168
172
 
169
173
  **EMUs (English Metric Unit)**
170
- EMUs are a virtual unit designed to facilitate the smooth conversion between inches, milliimeters, and pixels for images and vector graphics. 1in == 914400 EMUs == 72dpi x 100 x 254.
174
+ EMUs are a virtual unit designed to facilitate the smooth conversion between inches, millimeters, and pixels for images and vector graphics. 1in == 914400 EMUs == 72dpi x 100 x 254.
171
175
 
172
176
  At present, Caracal expects values to be specified in whichever unit OOXML requires. This is admittedly difficult for new Caracal users. Eventually, we'll probably implement a utility object under the hood to convert user-specified units into the format expected by OOXML.
173
177
 
174
178
 
175
179
  ## Syntax Flexibility
176
180
 
177
- Generally speaking, Caracal commands will accept instructions via any combination of a parameters hash and/or a block. For example, all of the folowing commands are equivalent.
181
+ Generally speaking, Caracal commands will accept instructions via any combination of a parameters hash and/or a block. For example, all of the following commands are equivalent.
178
182
 
179
183
  ```ruby
180
184
  docx.style id: 'special', name: 'Special', size: 24, bold: true
@@ -351,9 +355,28 @@ Caracal establishes a standard set of default styles for every document. Default
351
355
  * Heading6
352
356
 
353
357
 
358
+
359
+ ### Custom Properties
360
+
361
+ Custom document properties can be defined using the `custom_property` method. The method accepts a few required parameters to control the definition of the custom property.
362
+
363
+ ```ruby
364
+ docx.custom_property do
365
+ name 'property name 1' # sets the name of the custom property.
366
+ value 'test' # sets the value of the custom property.
367
+ type :text # sets the property type. accepts :text, :number, :date, :boolean.
368
+ end
369
+ ```
370
+
371
+ The `name`, `value`, and `height` attributes are required. If any of the attributes are missing, the custom property will not be created.
372
+
373
+ A document may have zero or many custom properties. Each custom property's `name` should be unique with its `type`.
374
+
375
+
376
+
354
377
  ### Paragraphs
355
378
 
356
- Paragraph text can be added using the `p` method. The method accepts several optional parameters for controlling the style and behavior of the paragrpah.
379
+ Paragraph text can be added using the `p` method. The method accepts several optional parameters for controlling the style and behavior of the paragraph.
357
380
 
358
381
  In its simple form, a paragraph accepts a text string and formatting options.
359
382
 
@@ -364,7 +387,7 @@ docx.p 'Sample text.', style: 'custom_style'
364
387
 
365
388
  docx.p 'Sample text.' do
366
389
  style 'custom_style' # sets the paragraph style. generally used at the exclusion of other attributes.
367
- align :left # sewts the alignment. accepts :left, :center, :right, and :both.
390
+ align :left # sets the alignment. accepts :left, :center, :right, and :both.
368
391
  color '333333' # sets the font color.
369
392
  size 32 # sets the font size. units in 1/2 points.
370
393
  bold true # sets whether or not to render the text with a bold weight.
@@ -384,6 +407,7 @@ docx.p do
384
407
  text '.'
385
408
  br
386
409
  text 'This text follows a line break.'
410
+ page
387
411
  end
388
412
  ```
389
413
 
@@ -565,7 +589,7 @@ docx.table [['Header 1','Header 2'],['Cell 1', 'Cell 2']] do
565
589
  border_color '666666' # sets the border color. defaults to 'auto'.
566
590
  border_line :single # sets the border style. defaults to :single. see OOXML docs for details.
567
591
  border_size 4 # sets the border width. defaults to 0. units in twips.
568
- border_spacing 4 # sets the spacing around the border. deaults to 0. units in twips.
592
+ border_spacing 4 # sets the spacing around the border. defaults to 0. units in twips.
569
593
  end
570
594
  ```
571
595
 
@@ -0,0 +1,47 @@
1
+ require 'caracal/core/models/custom_property_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to setting the
9
+ # document's custom properties.
10
+ #
11
+ module CustomProperties
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Public Methods
17
+ #-------------------------------------------------------------
18
+
19
+ # This method controls the custom properties.
20
+ #
21
+ def custom_property(options={}, &block)
22
+ model = Caracal::Core::Models::CustomPropertyModel.new(options, &block)
23
+ if model.valid?
24
+ register_property(model)
25
+ end
26
+ model
27
+ end
28
+
29
+ #============== GETTERS =============================
30
+
31
+ def custom_props
32
+ @custom_props ||= []
33
+ end
34
+
35
+ #============== REGISTRATION ========================
36
+
37
+ def register_property(model)
38
+ custom_props << model
39
+ model
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,60 @@
1
+ require 'caracal/core/models/base_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+ module Models
7
+
8
+ # This class encapsulates the logic needed to store and manipulate
9
+ # custom properties
10
+ #
11
+ class CustomPropertyModel < BaseModel
12
+
13
+ # accessors
14
+ attr_reader :custom_property_name
15
+ attr_reader :custom_property_value
16
+ attr_reader :custom_property_type
17
+
18
+
19
+ #-------------------------------------------------------------
20
+ # Public Instance Methods
21
+ #-------------------------------------------------------------
22
+
23
+
24
+ #=================== SETTERS =============================
25
+
26
+ def name(value)
27
+ @custom_property_name = value.to_s
28
+ end
29
+
30
+ def value(value)
31
+ @custom_property_value = value.to_s
32
+ end
33
+
34
+ def type(value)
35
+ @custom_property_type = value.to_s
36
+ end
37
+
38
+
39
+ #=============== VALIDATION ===========================
40
+
41
+ def valid?
42
+ required = option_keys
43
+ required.all? { |m| !send("custom_property_#{ m }").nil? }
44
+ end
45
+
46
+
47
+ #-------------------------------------------------------------
48
+ # Private Instance Methods
49
+ #-------------------------------------------------------------
50
+ private
51
+
52
+ def option_keys
53
+ [:name, :value, :type]
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -4,12 +4,58 @@ require 'caracal/core/models/base_model'
4
4
  module Caracal
5
5
  module Core
6
6
  module Models
7
-
7
+
8
8
  # This class encapsulates the logic needed to store and manipulate
9
9
  # page break data.
10
10
  #
11
- class PageBreakModel < BaseModel; end
12
-
11
+ # The :wrap option is not described in the project's README because
12
+ # it exists purely as an internal Caracal concern. Page breaks
13
+ # at the document level must be wrapped in a paragraph node; page breaks
14
+ # within paragraph-like container simply add a run. There's no need to
15
+ # trouble end users with this issue.
16
+ #
17
+ class PageBreakModel < BaseModel
18
+
19
+ #-------------------------------------------------------------
20
+ # Configuration
21
+ #-------------------------------------------------------------
22
+
23
+ # constants
24
+ const_set(:DEFAULT_PAGE_BREAK_WRAP, true)
25
+
26
+ # accessors
27
+ attr_reader :page_break_wrap
28
+
29
+ # initialization
30
+ def initialize(options={}, &block)
31
+ @page_break_wrap = DEFAULT_PAGE_BREAK_WRAP
32
+
33
+ super options, &block
34
+ end
35
+
36
+
37
+ #-------------------------------------------------------------
38
+ # Public Methods
39
+ #-------------------------------------------------------------
40
+
41
+ #=============== SETTERS ==============================
42
+
43
+ def wrap(value)
44
+ @page_break_wrap = !!value
45
+ end
46
+
47
+
48
+ #-------------------------------------------------------------
49
+ # Private Instance Methods
50
+ #-------------------------------------------------------------
51
+ private
52
+
53
+ def option_keys
54
+ [:wrap]
55
+ end
56
+
57
+ end
58
+
13
59
  end
14
60
  end
15
- end
61
+ end
@@ -92,6 +92,13 @@ module Caracal
92
92
 
93
93
  #=============== SUB-METHODS ===========================
94
94
 
95
+ # .br
96
+ def br
97
+ model = Caracal::Core::Models::LineBreakModel.new()
98
+ runs << model
99
+ model
100
+ end
101
+
95
102
  # .link
96
103
  def link(*args, &block)
97
104
  options = Caracal::Utilities.extract_options!(args)
@@ -107,9 +114,9 @@ module Caracal
107
114
  model
108
115
  end
109
116
 
110
- # .br
111
- def br
112
- model = Caracal::Core::Models::LineBreakModel.new()
117
+ # .page
118
+ def page
119
+ model = Caracal::Core::Models::PageBreakModel.new({ wrap: false })
113
120
  runs << model
114
121
  model
115
122
  end
@@ -9,6 +9,7 @@ require 'caracal/core/lists'
9
9
  require 'caracal/core/page_breaks'
10
10
  require 'caracal/core/page_numbers'
11
11
  require 'caracal/core/page_settings'
12
+ require 'caracal/core/custom_properties'
12
13
  require 'caracal/core/relationships'
13
14
  require 'caracal/core/rules'
14
15
  require 'caracal/core/styles'
@@ -18,6 +19,7 @@ require 'caracal/core/text'
18
19
  require 'caracal/renderers/app_renderer'
19
20
  require 'caracal/renderers/content_types_renderer'
20
21
  require 'caracal/renderers/core_renderer'
22
+ require 'caracal/renderers/custom_renderer'
21
23
  require 'caracal/renderers/document_renderer'
22
24
  require 'caracal/renderers/fonts_renderer'
23
25
  require 'caracal/renderers/footer_renderer'
@@ -30,97 +32,98 @@ require 'caracal/renderers/styles_renderer'
30
32
 
31
33
  module Caracal
32
34
  class Document
33
-
35
+
34
36
  #-------------------------------------------------------------
35
37
  # Configuration
36
38
  #-------------------------------------------------------------
37
-
39
+
38
40
  # mixins (order is important)
39
41
  include Caracal::Core::FileName
40
-
42
+ include Caracal::Core::CustomProperties
43
+
41
44
  include Caracal::Core::Relationships
42
45
  include Caracal::Core::Fonts
43
46
  include Caracal::Core::PageSettings
44
47
  include Caracal::Core::PageNumbers
45
48
  include Caracal::Core::Styles
46
49
  include Caracal::Core::ListStyles
47
-
50
+
48
51
  include Caracal::Core::Images
49
52
  include Caracal::Core::Lists
50
53
  include Caracal::Core::PageBreaks
51
54
  include Caracal::Core::Rules
52
55
  include Caracal::Core::Tables
53
56
  include Caracal::Core::Text
54
-
55
-
57
+
58
+
56
59
  #-------------------------------------------------------------
57
60
  # Public Class Methods
58
61
  #-------------------------------------------------------------
59
-
62
+
60
63
  #============ OUTPUT ====================================
61
-
64
+
62
65
  # This method renders a new Word document and returns it as a
63
66
  # a string.
64
67
  #
65
68
  def self.render(f_name = nil, &block)
66
69
  docx = new(f_name, &block)
67
70
  buffer = docx.render
68
-
71
+
69
72
  buffer.rewind
70
73
  buffer.sysread
71
74
  end
72
-
75
+
73
76
  # This method renders a new Word document and saves it to the
74
77
  # file system.
75
78
  #
76
79
  def self.save(f_name = nil, &block)
77
80
  docx = new(f_name, &block)
78
81
  buffer = docx.render
79
-
82
+
80
83
  File.open("./#{ docx.name }", 'w') { |f| f.write(buffer.string) }
81
84
  end
82
-
83
-
84
-
85
+
86
+
87
+
85
88
  #-------------------------------------------------------------
86
89
  # Public Instance Methods
87
90
  #-------------------------------------------------------------
88
-
91
+
89
92
  # This method instantiates a new word document.
90
93
  #
91
94
  def initialize(name = nil, &block)
92
95
  file_name(name)
93
-
94
- page_size
96
+
97
+ page_size
95
98
  page_margins top: 1440, bottom: 1440, left: 1440, right: 1440
96
99
  page_numbers
97
-
100
+
98
101
  [:relationship, :font, :style, :list_style].each do |method|
99
102
  collection = self.class.send("default_#{ method }s")
100
103
  collection.each do |item|
101
104
  send(method, item)
102
105
  end
103
106
  end
104
-
107
+
105
108
  if block_given?
106
109
  (block.arity < 1) ? instance_eval(&block) : block[self]
107
110
  end
108
111
  end
109
-
110
-
112
+
113
+
111
114
  #============ GETTERS ===================================
112
-
113
- # This method returns an array of models which constitute the
115
+
116
+ # This method returns an array of models which constitute the
114
117
  # set of instructions for producing the document content.
115
118
  #
116
119
  def contents
117
120
  @contents ||= []
118
121
  end
119
-
120
-
122
+
123
+
121
124
  #============ RENDERING =================================
122
-
123
- # This method renders the word document instance into
125
+
126
+ # This method renders the word document instance into
124
127
  # a string buffer. Order is important!
125
128
  #
126
129
  def render
@@ -129,6 +132,7 @@ module Caracal
129
132
  render_content_types(zip)
130
133
  render_app(zip)
131
134
  render_core(zip)
135
+ render_custom(zip)
132
136
  render_fonts(zip)
133
137
  render_footer(zip)
134
138
  render_settings(zip)
@@ -139,58 +143,65 @@ module Caracal
139
143
  render_numbering(zip) # Must go here: Depends on document renderer
140
144
  end
141
145
  end
142
-
143
-
144
-
146
+
147
+
148
+
145
149
  #-------------------------------------------------------------
146
150
  # Private Instance Methods
147
151
  #-------------------------------------------------------------
148
152
  private
149
-
153
+
150
154
  #============ RENDERERS =====================================
151
-
155
+
152
156
  def render_app(zip)
153
157
  content = ::Caracal::Renderers::AppRenderer.render(self)
154
-
158
+
155
159
  zip.put_next_entry('docProps/app.xml')
156
160
  zip.write(content)
157
161
  end
158
-
162
+
159
163
  def render_content_types(zip)
160
164
  content = ::Caracal::Renderers::ContentTypesRenderer.render(self)
161
-
165
+
162
166
  zip.put_next_entry('[Content_Types].xml')
163
167
  zip.write(content)
164
168
  end
165
-
169
+
166
170
  def render_core(zip)
167
171
  content = ::Caracal::Renderers::CoreRenderer.render(self)
168
-
172
+
169
173
  zip.put_next_entry('docProps/core.xml')
170
174
  zip.write(content)
171
175
  end
172
-
176
+
177
+ def render_custom(zip)
178
+ content = ::Caracal::Renderers::CustomRenderer.render(self)
179
+
180
+ zip.put_next_entry('docProps/custom.xml')
181
+ zip.write(content)
182
+ end
183
+
173
184
  def render_document(zip)
174
185
  content = ::Caracal::Renderers::DocumentRenderer.render(self)
175
-
186
+
176
187
  zip.put_next_entry('word/document.xml')
177
188
  zip.write(content)
178
189
  end
179
-
190
+
180
191
  def render_fonts(zip)
181
192
  content = ::Caracal::Renderers::FontsRenderer.render(self)
182
-
193
+
183
194
  zip.put_next_entry('word/fontTable.xml')
184
195
  zip.write(content)
185
196
  end
186
-
197
+
187
198
  def render_footer(zip)
188
199
  content = ::Caracal::Renderers::FooterRenderer.render(self)
189
-
200
+
190
201
  zip.put_next_entry('word/footer1.xml')
191
202
  zip.write(content)
192
203
  end
193
-
204
+
194
205
  def render_media(zip)
195
206
  images = relationships.select { |r| r.relationship_type == :image }
196
207
  images.each do |rel|
@@ -199,46 +210,46 @@ module Caracal
199
210
  else
200
211
  content = open(rel.relationship_target).read
201
212
  end
202
-
213
+
203
214
  zip.put_next_entry("word/#{ rel.formatted_target }")
204
215
  zip.write(content)
205
216
  end
206
217
  end
207
-
218
+
208
219
  def render_numbering(zip)
209
220
  content = ::Caracal::Renderers::NumberingRenderer.render(self)
210
-
221
+
211
222
  zip.put_next_entry('word/numbering.xml')
212
223
  zip.write(content)
213
224
  end
214
-
225
+
215
226
  def render_package_relationships(zip)
216
227
  content = ::Caracal::Renderers::PackageRelationshipsRenderer.render(self)
217
-
228
+
218
229
  zip.put_next_entry('_rels/.rels')
219
230
  zip.write(content)
220
231
  end
221
-
232
+
222
233
  def render_relationships(zip)
223
234
  content = ::Caracal::Renderers::RelationshipsRenderer.render(self)
224
-
235
+
225
236
  zip.put_next_entry('word/_rels/document.xml.rels')
226
237
  zip.write(content)
227
238
  end
228
-
239
+
229
240
  def render_settings(zip)
230
241
  content = ::Caracal::Renderers::SettingsRenderer.render(self)
231
-
242
+
232
243
  zip.put_next_entry('word/settings.xml')
233
244
  zip.write(content)
234
245
  end
235
-
246
+
236
247
  def render_styles(zip)
237
248
  content = ::Caracal::Renderers::StylesRenderer.render(self)
238
-
249
+
239
250
  zip.put_next_entry('word/styles.xml')
240
251
  zip.write(content)
241
252
  end
242
-
253
+
243
254
  end
244
255
  end
@@ -6,12 +6,12 @@ require 'caracal/renderers/xml_renderer'
6
6
  module Caracal
7
7
  module Renderers
8
8
  class ContentTypesRenderer < XmlRenderer
9
-
9
+
10
10
  #-------------------------------------------------------------
11
11
  # Public Methods
12
12
  #-------------------------------------------------------------
13
-
14
- # This method produces the xml required for the `_[ContentTypes].xml`
13
+
14
+ # This method produces the xml required for the `_[ContentTypes].xml`
15
15
  # sub-document.
16
16
  #
17
17
  def to_xml
@@ -23,31 +23,32 @@ module Caracal
23
23
  xml.send 'Default', { 'Extension' => 'png', 'ContentType' => 'image/png' }
24
24
  xml.send 'Default', { 'Extension' => 'rels', 'ContentType' => 'application/vnd.openxmlformats-package.relationships+xml' }
25
25
  xml.send 'Default', { 'Extension' => 'xml', 'ContentType' => 'application/xml' }
26
- xml.send 'Override', { 'PartName' => '/docProps/app.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.extended-properties+xml' }
27
- xml.send 'Override', { 'PartName' => '/docProps/core.xml', 'ContentType' => 'application/vnd.openxmlformats-package.core-properties+xml' }
28
- xml.send 'Override', { 'PartName' => '/word/document.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml' }
29
- xml.send 'Override', { 'PartName' => '/word/footer1.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml' }
30
- xml.send 'Override', { 'PartName' => '/word/fontTable.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml' }
31
- xml.send 'Override', { 'PartName' => '/word/numbering.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml' }
32
- xml.send 'Override', { 'PartName' => '/word/settings.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml' }
33
- xml.send 'Override', { 'PartName' => '/word/styles.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml' }
26
+ xml.send 'Override', { 'PartName' => '/docProps/app.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.extended-properties+xml' }
27
+ xml.send 'Override', { 'PartName' => '/docProps/core.xml', 'ContentType' => 'application/vnd.openxmlformats-package.core-properties+xml' }
28
+ xml.send 'Override', { 'PartName' => '/docProps/custom.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.custom-properties+xml' }
29
+ xml.send 'Override', { 'PartName' => '/word/document.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml' }
30
+ xml.send 'Override', { 'PartName' => '/word/footer1.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml' }
31
+ xml.send 'Override', { 'PartName' => '/word/fontTable.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml' }
32
+ xml.send 'Override', { 'PartName' => '/word/numbering.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml' }
33
+ xml.send 'Override', { 'PartName' => '/word/settings.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml' }
34
+ xml.send 'Override', { 'PartName' => '/word/styles.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml' }
34
35
  end
35
36
  end
36
37
  builder.to_xml(save_options)
37
38
  end
38
-
39
-
39
+
40
+
40
41
  #-------------------------------------------------------------
41
42
  # Private Methods
42
- #-------------------------------------------------------------
43
+ #-------------------------------------------------------------
43
44
  private
44
-
45
+
45
46
  def root_options
46
47
  {
47
48
  'xmlns' => 'http://schemas.openxmlformats.org/package/2006/content-types'
48
49
  }
49
50
  end
50
-
51
+
51
52
  end
52
53
  end
53
- end
54
+ end
@@ -0,0 +1,64 @@
1
+ require 'nokogiri'
2
+ require 'date'
3
+
4
+ require 'caracal/renderers/xml_renderer'
5
+
6
+
7
+ module Caracal
8
+ module Renderers
9
+ class CustomRenderer < XmlRenderer
10
+
11
+ #-------------------------------------------------------------
12
+ # Public Methods
13
+ #-------------------------------------------------------------
14
+
15
+ # This method produces the xml required for the `docProps/custom.xml`
16
+ # sub-document.
17
+ #
18
+ def to_xml
19
+ builder = ::Nokogiri::XML::Builder.with(declaration_xml) do |xml|
20
+ xml.send 'Properties', root_options do
21
+ document.custom_props.each_with_index do |property, index|
22
+ xml.send 'property',
23
+ { fmtid: '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}', pid: index + 2, name: property.custom_property_name } do
24
+ case property.custom_property_type.downcase
25
+ when 'text'
26
+ xml['vt'].lpwstr property.custom_property_value
27
+ when 'date'
28
+ xml['vt'].filetime property.custom_property_value.to_date
29
+ when 'number'
30
+ xml['vt'].i4 property.custom_property_value.to_f
31
+ when 'boolean'
32
+ if property.custom_property_value == 'true' || property.custom_property_value == 'false'
33
+ xml['vt'].bool property.custom_property_value
34
+ else
35
+ # Not a boolean sent, so reverting to string so docx will open
36
+ xml['vt'].lpwstr property.custom_property_value
37
+ end
38
+ else
39
+ # Fail to string type
40
+ xml['vt'].lpwstr property.custom_property_value
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ builder.to_xml(save_options)
47
+ end
48
+
49
+
50
+ #-------------------------------------------------------------
51
+ # Private Methods
52
+ #-------------------------------------------------------------
53
+ private
54
+
55
+ def root_options
56
+ {
57
+ 'xmlns' => "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties",
58
+ 'xmlns:vt' => "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
59
+ }
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -205,7 +205,13 @@ module Caracal
205
205
  end
206
206
 
207
207
  def render_pagebreak(xml, model)
208
- xml.send 'w:p', paragraph_options do
208
+ if model.page_break_wrap
209
+ xml.send 'w:p', paragraph_options do
210
+ xml.send 'w:r', run_options do
211
+ xml.send 'w:br', { 'w:type' => 'page' }
212
+ end
213
+ end
214
+ else
209
215
  xml.send 'w:r', run_options do
210
216
  xml.send 'w:br', { 'w:type' => 'page' }
211
217
  end
@@ -6,12 +6,12 @@ require 'caracal/renderers/xml_renderer'
6
6
  module Caracal
7
7
  module Renderers
8
8
  class PackageRelationshipsRenderer < XmlRenderer
9
-
9
+
10
10
  #-------------------------------------------------------------
11
11
  # Public Methods
12
12
  #-------------------------------------------------------------
13
-
14
- # This method produces the xml required for the `word/settings.xml`
13
+
14
+ # This method produces the xml required for the `word/settings.xml`
15
15
  # sub-document.
16
16
  #
17
17
  def to_xml
@@ -24,27 +24,28 @@ module Caracal
24
24
  end
25
25
  builder.to_xml(save_options)
26
26
  end
27
-
28
-
27
+
28
+
29
29
  #-------------------------------------------------------------
30
30
  # Private Methods
31
- #-------------------------------------------------------------
31
+ #-------------------------------------------------------------
32
32
  private
33
-
33
+
34
34
  def relationship_data
35
35
  [
36
- ['docProps/app.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'],
37
- ['docProps/core.xml', 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties'],
38
- ['word/document.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument']
36
+ ['docProps/app.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'],
37
+ ['docProps/core.xml', 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties'],
38
+ ['docProps/custom.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties'],
39
+ ['word/document.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument']
39
40
  ]
40
41
  end
41
-
42
+
42
43
  def root_options
43
44
  {
44
45
  'xmlns' => 'http://schemas.openxmlformats.org/package/2006/relationships'
45
46
  }
46
47
  end
47
-
48
+
48
49
  end
49
50
  end
50
- end
51
+ end
@@ -4,80 +4,80 @@ require 'nokogiri'
4
4
  module Caracal
5
5
  module Renderers
6
6
  class XmlRenderer
7
-
7
+
8
8
  #-------------------------------------------------------------
9
9
  # Configuration
10
10
  #-------------------------------------------------------------
11
-
11
+
12
12
  attr_reader :document
13
-
14
-
13
+
14
+
15
15
  #-------------------------------------------------------------
16
16
  # Class Methods
17
17
  #-------------------------------------------------------------
18
-
19
- # This method produces xml output for the given document
18
+
19
+ # This method produces xml output for the given document
20
20
  # according to the rules of this renderer object.
21
21
  #
22
22
  def self.render(doc)
23
23
  renderer = new(doc)
24
24
  renderer.to_xml
25
25
  end
26
-
27
-
26
+
27
+
28
28
  #-------------------------------------------------------------
29
29
  # Public Methods
30
30
  #-------------------------------------------------------------
31
-
31
+
32
32
  # This method instantiates a new verison of this renderer.
33
33
  #
34
34
  def initialize(doc)
35
35
  unless doc.is_a?(Caracal::Document)
36
36
  raise NoDocumentError, 'renderers must receive a reference to a valid Caracal document object.'
37
37
  end
38
-
38
+
39
39
  @document = doc
40
40
  end
41
-
41
+
42
42
  # This method converts data in the specified document to XML.
43
43
  # A concrete implementation must be provided by the subclass.
44
44
  #
45
45
  def to_xml
46
46
  raise NotImplementedError, 'renderers must implement the method :to_xml.'
47
47
  end
48
-
49
-
48
+
49
+
50
50
  #-------------------------------------------------------------
51
51
  # Private Methods
52
52
  #-------------------------------------------------------------
53
53
  private
54
-
55
- # This method returns a Nokogiri::XML object that contains the
54
+
55
+ # This method returns a Nokogiri::XML object that contains the
56
56
  # specific declaration we want.
57
57
  #
58
58
  def declaration_xml
59
59
  ::Nokogiri::XML('<?xml version = "1.0" encoding = "UTF-8" standalone ="yes"?>')
60
60
  end
61
-
61
+
62
62
  # This method returns a commonly used set of attributes for paragraph nodes.
63
63
  #
64
64
  def paragraph_options
65
65
  { 'w:rsidP' => '00000000', 'w:rsidRDefault' => '00000000' }.merge(run_options)
66
66
  end
67
-
67
+
68
68
  # This method returns a commonly used set of attributes for text run nodes.
69
69
  #
70
70
  def run_options
71
71
  { 'w:rsidR' => '00000000', 'w:rsidRPr' => '00000000', 'w:rsidDel' => '00000000' }
72
72
  end
73
-
73
+
74
74
  # These save options force Nokogiri to remove indentation and
75
75
  # line feeds from the output.
76
76
  #
77
77
  def save_options
78
78
  { save_with: Nokogiri::XML::Node::SaveOptions::AS_XML }
79
79
  end
80
-
80
+
81
81
  end
82
82
  end
83
- end
83
+ end
@@ -1,3 +1,3 @@
1
1
  module Caracal
2
- VERSION = '1.0.2'
2
+ VERSION = '1.0.3'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caracal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trade Infomatics
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-12-09 00:00:00.000000000 Z
12
+ date: 2016-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -112,6 +112,7 @@ files:
112
112
  - Rakefile
113
113
  - caracal.gemspec
114
114
  - lib/caracal.rb
115
+ - lib/caracal/core/custom_properties.rb
115
116
  - lib/caracal/core/file_name.rb
116
117
  - lib/caracal/core/fonts.rb
117
118
  - lib/caracal/core/images.rb
@@ -119,6 +120,7 @@ files:
119
120
  - lib/caracal/core/lists.rb
120
121
  - lib/caracal/core/models/base_model.rb
121
122
  - lib/caracal/core/models/border_model.rb
123
+ - lib/caracal/core/models/custom_property_model.rb
122
124
  - lib/caracal/core/models/font_model.rb
123
125
  - lib/caracal/core/models/image_model.rb
124
126
  - lib/caracal/core/models/line_break_model.rb
@@ -150,6 +152,7 @@ files:
150
152
  - lib/caracal/renderers/app_renderer.rb
151
153
  - lib/caracal/renderers/content_types_renderer.rb
152
154
  - lib/caracal/renderers/core_renderer.rb
155
+ - lib/caracal/renderers/custom_renderer.rb
153
156
  - lib/caracal/renderers/document_renderer.rb
154
157
  - lib/caracal/renderers/fonts_renderer.rb
155
158
  - lib/caracal/renderers/footer_renderer.rb