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 +4 -4
- data/CHANGELOG.md +11 -5
- data/README.md +29 -5
- data/lib/caracal/core/custom_properties.rb +47 -0
- data/lib/caracal/core/models/custom_property_model.rb +60 -0
- data/lib/caracal/core/models/page_break_model.rb +50 -4
- data/lib/caracal/core/models/paragraph_model.rb +10 -3
- data/lib/caracal/document.rb +67 -56
- data/lib/caracal/renderers/content_types_renderer.rb +18 -17
- data/lib/caracal/renderers/custom_renderer.rb +64 -0
- data/lib/caracal/renderers/document_renderer.rb +7 -1
- data/lib/caracal/renderers/package_relationships_renderer.rb +14 -13
- data/lib/caracal/renderers/xml_renderer.rb +20 -20
- data/lib/caracal/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c858148d5ae537806007e2e90609ef72cb78aaad
|
4
|
+
data.tar.gz: e92af27b1c79d1842ed2aac515aedfe0452bb53c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 (@
|
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. (@
|
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,
|
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
|
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
|
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 #
|
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.
|
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
|
-
|
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
|
-
# .
|
111
|
-
def
|
112
|
-
model = Caracal::Core::Models::
|
117
|
+
# .page
|
118
|
+
def page
|
119
|
+
model = Caracal::Core::Models::PageBreakModel.new({ wrap: false })
|
113
120
|
runs << model
|
114
121
|
model
|
115
122
|
end
|
data/lib/caracal/document.rb
CHANGED
@@ -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',
|
27
|
-
xml.send 'Override', { 'PartName' => '/docProps/core.xml',
|
28
|
-
xml.send 'Override', { 'PartName' => '/
|
29
|
-
xml.send 'Override', { 'PartName' => '/word/
|
30
|
-
xml.send 'Override', { 'PartName' => '/word/
|
31
|
-
xml.send 'Override', { 'PartName' => '/word/
|
32
|
-
xml.send 'Override', { 'PartName' => '/word/
|
33
|
-
xml.send 'Override', { 'PartName' => '/word/
|
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
|
-
|
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',
|
37
|
-
['docProps/core.xml',
|
38
|
-
['
|
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
|
data/lib/caracal/version.rb
CHANGED
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.
|
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:
|
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
|