caracal 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/README.md +41 -40
- data/lib/caracal/core/models/style_model.rb +31 -29
- data/lib/caracal/core/models/table_model.rb +5 -5
- data/lib/caracal/renderers/styles_renderer.rb +23 -21
- data/lib/caracal/version.rb +1 -1
- data/spec/lib/caracal/core/models/style_model_spec.rb +51 -44
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40031dc07952a23e5f4f7f5528155f2b81d1d9e4
|
4
|
+
data.tar.gz: d015ece8fef1d66888e8f2f851705b02bdb34dce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ee50065caf4feaca536714e7b6b1feee99fa479986f5e9ae995cc14f3d268487db7301e1f4ee3b8bf4764d13ac3cae77c1eac9aba5792c7a5d633813cfa5996
|
7
|
+
data.tar.gz: 1442f8a0e3d543a6174d7daea7d1992ae3a278c3d5ca48d141675def7ec982e799217b13306c2949517b72b8465b35f8945dfcfea761afc81161b1863f0836ab
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
#### Unreleased
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
* Added :caps attribute to paragraph styles (@jensljungblad)
|
5
|
+
|
6
|
+
|
7
|
+
|
1
8
|
#### v0.2.0
|
2
9
|
|
3
10
|
* Enhancements
|
@@ -14,4 +21,4 @@
|
|
14
21
|
#### v0.1.x
|
15
22
|
|
16
23
|
* Enhancements
|
17
|
-
* Initial commits. (@jpdugan)
|
24
|
+
* Initial commits. (@jpdugan)
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ Caracal::Document.save 'example.docx' do |docx|
|
|
29
29
|
docx.table @my_data, border_size: 4 do
|
30
30
|
cell_style rows[0], background: 'cccccc', bold: true
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# page 2
|
34
34
|
docx.page
|
35
35
|
docx.h1 'Page 2 Header'
|
@@ -55,10 +55,10 @@ We created Caracal to satisfy a genuine business requirement. We were working o
|
|
55
55
|
|
56
56
|
Now, as you may have noticed, the Ruby community has never exactly been known for its enthusiastic support of Microsoft standards. So it might not surprise you to learn that the existing options on Rubygems for Word document generation were limited. Those libraries, by and large, fell into a couple of categories:
|
57
57
|
|
58
|
-
* **HTML to Word Convertors**
|
58
|
+
* **HTML to Word Convertors**
|
59
59
|
We understand the motivating idea here (two output streams from one set of instructions), but the reality is the number of possible permutations of nested HTML tags is simply too great for this strategy to ever work for anything other than the simplest kinds of documents. Most of these libraries rely on a number of undocumented assumptions about the structure of your HTML (which undermines the whole value proposition of a convertor) and fail to support basic features of a professional-quality Word document (e.g., images, lists, tables, etc). The remaining libraries simply did not work at all.
|
60
60
|
|
61
|
-
* **Weekend Projects**
|
61
|
+
* **Weekend Projects**
|
62
62
|
We also found a number of inactive projects that appeared to be experiments in the space. Obviously, these libraries were out of the question for a commercial product.
|
63
63
|
|
64
64
|
What we wanted was a Prawn-style library for the `:docx` format. In the absence of an active project organized along those lines, we decided to write one.
|
@@ -107,40 +107,40 @@ For each Caracal request, the following document structure will be created and z
|
|
107
107
|
|
108
108
|
The following provides a brief description for each component of the final document:
|
109
109
|
|
110
|
-
**_rels/.rels**
|
110
|
+
**_rels/.rels**
|
111
111
|
Defines an internal identifier and type for global content items. *This file is generated automatically by the library based on other user directives.*
|
112
112
|
|
113
|
-
**docProps/app.xml**
|
113
|
+
**docProps/app.xml**
|
114
114
|
Specifies the name of the application that generated the document. *This file is generated automatically by the library based on other user directives.*
|
115
115
|
|
116
|
-
**docProps/core.xml**
|
116
|
+
**docProps/core.xml**
|
117
117
|
Specifies the title of the document. *This file is generated automatically by the library based on other user directives.*
|
118
118
|
|
119
|
-
**word/_rels/document.xml.rels**
|
119
|
+
**word/_rels/document.xml.rels**
|
120
120
|
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.*
|
121
121
|
|
122
|
-
**word/media/**
|
122
|
+
**word/media/**
|
123
123
|
A collection of media assets (each of which should have an entry in document.xml.rels).
|
124
124
|
|
125
|
-
**word/document.xml**
|
125
|
+
**word/document.xml**
|
126
126
|
The main content file for the document.
|
127
127
|
|
128
|
-
**word/fontTable.xml**
|
128
|
+
**word/fontTable.xml**
|
129
129
|
Specifies the fonts used in the document.
|
130
130
|
|
131
|
-
**word/footer.xml**
|
131
|
+
**word/footer.xml**
|
132
132
|
Defines the formatting of the document footer.
|
133
133
|
|
134
|
-
**word/numbering.xml**
|
134
|
+
**word/numbering.xml**
|
135
135
|
Defines ordered and unordered list styles.
|
136
136
|
|
137
|
-
**word/settings.xml**
|
137
|
+
**word/settings.xml**
|
138
138
|
Defines global directives for the document (e.g., whether to show background images, tab widths, etc). Also, establishes compatibility with older versions on Word.
|
139
139
|
|
140
|
-
**word/styles.xml**
|
140
|
+
**word/styles.xml**
|
141
141
|
Defines all paragraph and table styles used through the document. Caracal adds a default set of styles to match its HTML-like content syntax. These defaults can be overridden.
|
142
142
|
|
143
|
-
**[Content_Types].xml**
|
143
|
+
**[Content_Types].xml**
|
144
144
|
Pairs extensions and XML files with schema content types so Word can parse them correctly. *This file is generated automatically by the library based on other user directives.*
|
145
145
|
|
146
146
|
|
@@ -148,25 +148,25 @@ Pairs extensions and XML files with schema content types so Word can parse them
|
|
148
148
|
|
149
149
|
OpenXML properties are specified in several different units, depending on which attribute is being set.
|
150
150
|
|
151
|
-
**Points**
|
151
|
+
**Points**
|
152
152
|
Most spacing declarations are measured in full points.
|
153
153
|
|
154
|
-
**Half Points**
|
154
|
+
**Half Points**
|
155
155
|
All font sizes are measure in half points. A font size of 24 is equivalent to 12pt.
|
156
156
|
|
157
|
-
**Eighth Points**
|
157
|
+
**Eighth Points**
|
158
158
|
Borders are measured in 1/8 points. A border size of 4 is equivalent to 0.5pt.
|
159
159
|
|
160
|
-
**Twips**
|
160
|
+
**Twips**
|
161
161
|
A twip is 1/20 of a point. Word documents are printed at 72dpi. 1in == 72pt == 1440 twips.
|
162
162
|
|
163
|
-
**Pixels**
|
163
|
+
**Pixels**
|
164
164
|
In Word documents, pixels are equivalent to points.
|
165
165
|
|
166
|
-
**EMUs (English Metric Unit)**
|
166
|
+
**EMUs (English Metric Unit)**
|
167
167
|
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.
|
168
168
|
|
169
|
-
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.
|
169
|
+
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.
|
170
170
|
|
171
171
|
|
172
172
|
## Syntax Flexibility
|
@@ -263,7 +263,7 @@ Both the `width` and `height` attributes require positive integer values.
|
|
263
263
|
### Page Margins
|
264
264
|
|
265
265
|
Page margins can be set using the `page_margins` method. The method accepts four parameters for controlling the margins of the document.
|
266
|
-
|
266
|
+
|
267
267
|
*Margins default to 1.0in for all sides.*
|
268
268
|
|
269
269
|
```ruby
|
@@ -302,7 +302,7 @@ end
|
|
302
302
|
|
303
303
|
### Fonts
|
304
304
|
|
305
|
-
Fonts are added to the font table file by calling the `font` method and passing the name of the font.
|
305
|
+
Fonts are added to the font table file by calling the `font` method and passing the name of the font.
|
306
306
|
|
307
307
|
*At present, Caracal only supports declaring the primary font name.*
|
308
308
|
|
@@ -326,7 +326,8 @@ docx.style do
|
|
326
326
|
size 28 # sets the font size. units in half points.
|
327
327
|
bold false # sets the font weight.
|
328
328
|
italic false # sets the font style.
|
329
|
-
underline false # sets whether or not to underline the text.
|
329
|
+
underline false # sets whether or not to underline the text.
|
330
|
+
caps false # sets whether or not text should be rendered in all capital letters.
|
330
331
|
align :left # sets the alignment. accepts :left, :center, :right, and :both.
|
331
332
|
line 360 # sets the line height. units in twips.
|
332
333
|
top 100 # sets the spacing above the paragraph. units in twips.
|
@@ -349,7 +350,7 @@ Caracal establishes a standard set of default styles for every document. Default
|
|
349
350
|
|
350
351
|
### Paragraphs
|
351
352
|
|
352
|
-
Paragraph text can be added using the `p` method. The method accepts several optional parameters for controlling the style and behavior of the paragrpah.
|
353
|
+
Paragraph text can be added using the `p` method. The method accepts several optional parameters for controlling the style and behavior of the paragrpah.
|
353
354
|
|
354
355
|
In its simple form, a paragraph accepts a text string and formatting options.
|
355
356
|
|
@@ -385,7 +386,7 @@ end
|
|
385
386
|
|
386
387
|
### Links
|
387
388
|
|
388
|
-
Links can be added inside paragraphs using the `link` method. The method accepts several optional parameters for controlling the style and behavior of the rule.
|
389
|
+
Links can be added inside paragraphs using the `link` method. The method accepts several optional parameters for controlling the style and behavior of the rule.
|
389
390
|
|
390
391
|
*At present, all links are assumed to be external.*
|
391
392
|
|
@@ -420,7 +421,7 @@ end
|
|
420
421
|
|
421
422
|
### Rules
|
422
423
|
|
423
|
-
Horizontal rules can be added using the `hr` method. The method accepts several optional parameters for controlling the style of the rule.
|
424
|
+
Horizontal rules can be added using the `hr` method. The method accepts several optional parameters for controlling the style of the rule.
|
424
425
|
|
425
426
|
```ruby
|
426
427
|
docx.hr do
|
@@ -458,7 +459,7 @@ Ordered lists can be added using the `ol` and `li` methods. The `li` method sub
|
|
458
459
|
```ruby
|
459
460
|
docx.ol do
|
460
461
|
li 'First item'
|
461
|
-
li do
|
462
|
+
li do
|
462
463
|
text 'Second item with a '
|
463
464
|
link 'link', 'http://www.google.com'
|
464
465
|
text '.'
|
@@ -473,7 +474,7 @@ Similarly, unordered lists can be added using the `ul` and `li` methods.
|
|
473
474
|
```ruby
|
474
475
|
docx.ul do
|
475
476
|
li 'First item'
|
476
|
-
li do
|
477
|
+
li do
|
477
478
|
text 'Second item with a '
|
478
479
|
link 'link', 'http://www.google.com'
|
479
480
|
text '.'
|
@@ -497,7 +498,7 @@ docx.ul do
|
|
497
498
|
end
|
498
499
|
end
|
499
500
|
end
|
500
|
-
end
|
501
|
+
end
|
501
502
|
end
|
502
503
|
```
|
503
504
|
|
@@ -514,7 +515,7 @@ docx.list_style do
|
|
514
515
|
level 2 # sets the nesting level. 0-based index.
|
515
516
|
format 'decimal' # sets the list style. see OOXML docs for details.
|
516
517
|
value '%3.' # sets the value of the list item marker. see OOXML docs for details.
|
517
|
-
align :left # sets the alignment. accepts :left, :center: and :right. defaults to :left.
|
518
|
+
align :left # sets the alignment. accepts :left, :center: and :right. defaults to :left.
|
518
519
|
indent 400 # sets the indention of the marker from the margin. units in twips.
|
519
520
|
left 800 # sets the indention of the text from the margin. units in twips.
|
520
521
|
start 2 # sets the number at which item counts begin. defaults to 1.
|
@@ -542,9 +543,9 @@ docx.img image_url('example.png') do
|
|
542
543
|
end
|
543
544
|
```
|
544
545
|
|
545
|
-
*Note: If you provide the image data, you should still supply a URL. I know this
|
546
|
-
is a bit hacky, but it allows the library to key the image more effectively and
|
547
|
-
Caracal needs a file extension to apply to the renamed media file. This seemed
|
546
|
+
*Note: If you provide the image data, you should still supply a URL. I know this
|
547
|
+
is a bit hacky, but it allows the library to key the image more effectively and
|
548
|
+
Caracal needs a file extension to apply to the renamed media file. This seemed
|
548
549
|
the simplest solution to both problems.*
|
549
550
|
|
550
551
|
|
@@ -557,7 +558,7 @@ The `table` command accepts data in the form of a two-dimensional arrays. This c
|
|
557
558
|
```ruby
|
558
559
|
docx.table [['Header 1','Header 2'],['Cell 1', 'Cell 2']] do
|
559
560
|
border_color '666666' # sets the border color. defaults to 'auto'.
|
560
|
-
border_line :single # sets the border style. defaults to :single. see OOXML docs for details.
|
561
|
+
border_line :single # sets the border style. defaults to :single. see OOXML docs for details.
|
561
562
|
border_size 4 # sets the border width. defaults to 0. units in twips.
|
562
563
|
border_spacing 4 # sets the spacing around the border. deaults to 0. units in twips.
|
563
564
|
end
|
@@ -592,7 +593,7 @@ end
|
|
592
593
|
|
593
594
|
### Table Cells
|
594
595
|
|
595
|
-
If your table contains more complex data (multiple paragraphs, images, lists, etc.), you will probably want to instantiate your `TableCellModel` instances directly. With the exception of page breaks, table cells can contain anything the document can contain, including another table.
|
596
|
+
If your table contains more complex data (multiple paragraphs, images, lists, etc.), you will probably want to instantiate your `TableCellModel` instances directly. With the exception of page breaks, table cells can contain anything the document can contain, including another table.
|
596
597
|
|
597
598
|
```ruby
|
598
599
|
c1 = Caracal::Core::Models:TableCellModel.new do
|
@@ -603,11 +604,11 @@ c1 = Caracal::Core::Models:TableCellModel.new do
|
|
603
604
|
left # sets the left margin. defaults to 0. units in twips.
|
604
605
|
right # sets the right margin. defaults to 0. units in twips.
|
605
606
|
end
|
606
|
-
|
607
|
+
|
607
608
|
p 'This is a sentence above an image.'
|
608
609
|
p
|
609
610
|
img image_url('example.png'), width: 200, height: 100
|
610
|
-
end
|
611
|
+
end
|
611
612
|
```
|
612
613
|
|
613
614
|
|
@@ -640,7 +641,7 @@ end
|
|
640
641
|
|
641
642
|
## Template Rendering
|
642
643
|
|
643
|
-
Caracal includes [Tilt](https://github.com/rtomayko/tilt) integration to facilitate its inclusion in other frameworks.
|
644
|
+
Caracal includes [Tilt](https://github.com/rtomayko/tilt) integration to facilitate its inclusion in other frameworks.
|
644
645
|
|
645
646
|
Rails integration can be added via the [Caracal-Rails](https://github.com/trade-informatics/caracal-rails) gem.
|
646
647
|
|
@@ -4,29 +4,30 @@ 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
|
# paragraph style data.
|
10
10
|
#
|
11
11
|
class StyleModel < BaseModel
|
12
|
-
|
12
|
+
|
13
13
|
#-------------------------------------------------------------
|
14
14
|
# Configuration
|
15
15
|
#-------------------------------------------------------------
|
16
|
-
|
16
|
+
|
17
17
|
# constants
|
18
18
|
const_set(:DEFAULT_STYLE_COLOR, '333333')
|
19
19
|
const_set(:DEFAULT_STYLE_SIZE, 20)
|
20
20
|
const_set(:DEFAULT_STYLE_BOLD, false)
|
21
21
|
const_set(:DEFAULT_STYLE_ITALIC, false)
|
22
22
|
const_set(:DEFAULT_STYLE_UNDERLINE, false)
|
23
|
+
const_set(:DEFAULT_STYLE_CAPS, false)
|
23
24
|
const_set(:DEFAULT_STYLE_ALIGN, :left)
|
24
25
|
const_set(:DEFAULT_STYLE_LINE, 360) # 0.25in in twips
|
25
26
|
const_set(:DEFAULT_STYLE_TOP, 0) # 0.0in in twips
|
26
27
|
const_set(:DEFAULT_STYLE_BOTTOM, 0) # 0.0in in twips
|
27
28
|
const_set(:DEFAULT_STYLE_BASE, 'Normal')
|
28
29
|
const_set(:DEFAULT_STYLE_NEXT, 'Normal')
|
29
|
-
|
30
|
+
|
30
31
|
# accessors
|
31
32
|
attr_reader :style_default
|
32
33
|
attr_reader :style_id
|
@@ -37,22 +38,22 @@ module Caracal
|
|
37
38
|
attr_reader :style_bold
|
38
39
|
attr_reader :style_italic
|
39
40
|
attr_reader :style_underline
|
41
|
+
attr_reader :style_caps
|
40
42
|
attr_reader :style_align
|
41
43
|
attr_reader :style_top
|
42
44
|
attr_reader :style_bottom
|
43
45
|
attr_reader :style_line
|
44
46
|
attr_reader :style_base
|
45
47
|
attr_reader :style_next
|
46
|
-
|
47
|
-
|
48
|
+
|
48
49
|
# initialization
|
49
50
|
def initialize(options={}, &block)
|
50
51
|
@style_default = false
|
51
52
|
@style_base = DEFAULT_STYLE_BASE
|
52
53
|
@style_next = DEFAULT_STYLE_NEXT
|
53
|
-
|
54
|
+
|
54
55
|
super options, &block
|
55
|
-
|
56
|
+
|
56
57
|
if (style_id == DEFAULT_STYLE_BASE)
|
57
58
|
@style_default ||= true
|
58
59
|
@style_color ||= DEFAULT_STYLE_COLOR
|
@@ -60,75 +61,76 @@ module Caracal
|
|
60
61
|
@style_bold ||= DEFAULT_STYLE_BOLD
|
61
62
|
@style_italic ||= DEFAULT_STYLE_ITALIC
|
62
63
|
@style_underline ||= DEFAULT_STYLE_UNDERLINE
|
64
|
+
@style_caps ||= DEFAULT_STYLE_CAPS
|
63
65
|
@style_align ||= DEFAULT_STYLE_ALIGN
|
64
66
|
@style_top ||= DEFAULT_STYLE_TOP
|
65
67
|
@style_bottom ||= DEFAULT_STYLE_BOTTOM
|
66
68
|
@style_line ||= DEFAULT_STYLE_LINE
|
67
69
|
end
|
68
70
|
end
|
69
|
-
|
70
|
-
|
71
|
+
|
72
|
+
|
71
73
|
#-------------------------------------------------------------
|
72
74
|
# Public Instance Methods
|
73
75
|
#-------------------------------------------------------------
|
74
|
-
|
76
|
+
|
75
77
|
#=============== SETTERS ==============================
|
76
|
-
|
78
|
+
|
77
79
|
# booleans
|
78
|
-
[:bold, :italic, :underline].each do |m|
|
80
|
+
[:bold, :italic, :underline, :caps].each do |m|
|
79
81
|
define_method "#{ m }" do |value|
|
80
82
|
instance_variable_set("@style_#{ m }", !!value)
|
81
83
|
end
|
82
84
|
end
|
83
|
-
|
85
|
+
|
84
86
|
# integers
|
85
87
|
[:bottom, :size, :line, :top].each do |m|
|
86
88
|
define_method "#{ m }" do |value|
|
87
89
|
instance_variable_set("@style_#{ m }", value.to_i)
|
88
90
|
end
|
89
91
|
end
|
90
|
-
|
92
|
+
|
91
93
|
# strings
|
92
94
|
[:id, :name, :color, :font].each do |m|
|
93
95
|
define_method "#{ m }" do |value|
|
94
96
|
instance_variable_set("@style_#{ m }", value.to_s)
|
95
97
|
end
|
96
98
|
end
|
97
|
-
|
99
|
+
|
98
100
|
# symbols
|
99
101
|
[:align].each do |m|
|
100
102
|
define_method "#{ m }" do |value|
|
101
103
|
instance_variable_set("@style_#{ m }", value.to_s.to_sym)
|
102
104
|
end
|
103
105
|
end
|
104
|
-
|
105
|
-
|
106
|
+
|
107
|
+
|
106
108
|
#=============== STATE ================================
|
107
|
-
|
109
|
+
|
108
110
|
def matches?(str)
|
109
111
|
style_id.downcase == str.to_s.downcase
|
110
112
|
end
|
111
|
-
|
112
|
-
|
113
|
+
|
114
|
+
|
113
115
|
#=============== VALIDATION ===========================
|
114
|
-
|
116
|
+
|
115
117
|
def valid?
|
116
118
|
a = [:id, :name]
|
117
119
|
a.map { |m| send("style_#{ m }") }.compact.size == a.size
|
118
120
|
end
|
119
|
-
|
120
|
-
|
121
|
+
|
122
|
+
|
121
123
|
#-------------------------------------------------------------
|
122
124
|
# Private Instance Methods
|
123
125
|
#-------------------------------------------------------------
|
124
126
|
private
|
125
|
-
|
127
|
+
|
126
128
|
def option_keys
|
127
|
-
[:bold, :italic, :underline, :top, :bottom, :size, :line, :id, :name, :color, :font, :align]
|
129
|
+
[:bold, :italic, :underline, :caps, :top, :bottom, :size, :line, :id, :name, :color, :font, :align]
|
128
130
|
end
|
129
|
-
|
131
|
+
|
130
132
|
end
|
131
|
-
|
133
|
+
|
132
134
|
end
|
133
135
|
end
|
134
|
-
end
|
136
|
+
end
|
@@ -154,12 +154,12 @@ module Caracal
|
|
154
154
|
begin
|
155
155
|
@table_data = value.map do |data_row|
|
156
156
|
data_row.map do |data_cell|
|
157
|
-
case data_cell
|
158
|
-
when
|
157
|
+
case data_cell
|
158
|
+
when Caracal::Core::Models::TableCellModel
|
159
159
|
data_cell
|
160
|
-
when
|
160
|
+
when Hash
|
161
161
|
Caracal::Core::Models::TableCellModel.new(data_cell)
|
162
|
-
when
|
162
|
+
when Proc
|
163
163
|
Caracal::Core::Models::TableCellModel.new(&data_cell)
|
164
164
|
else
|
165
165
|
Caracal::Core::Models::TableCellModel.new({ content: data_cell.to_s })
|
@@ -203,4 +203,4 @@ module Caracal
|
|
203
203
|
|
204
204
|
end
|
205
205
|
end
|
206
|
-
end
|
206
|
+
end
|
@@ -7,20 +7,20 @@ require 'caracal/errors'
|
|
7
7
|
module Caracal
|
8
8
|
module Renderers
|
9
9
|
class StylesRenderer < XmlRenderer
|
10
|
-
|
10
|
+
|
11
11
|
#-------------------------------------------------------------
|
12
12
|
# Public Methods
|
13
13
|
#-------------------------------------------------------------
|
14
|
-
|
15
|
-
# This method produces the xml required for the `word/styles.xml`
|
14
|
+
|
15
|
+
# This method produces the xml required for the `word/styles.xml`
|
16
16
|
# sub-document.
|
17
17
|
#
|
18
18
|
def to_xml
|
19
19
|
builder = ::Nokogiri::XML::Builder.with(declaration_xml) do |xml|
|
20
20
|
xml.send 'w:styles', root_options do
|
21
|
-
|
21
|
+
|
22
22
|
#============ DEFAULT STYLES ================================
|
23
|
-
|
23
|
+
|
24
24
|
unless s = document.default_style
|
25
25
|
raise Caracal::Errors::NoDefaultStyleError 'Document must declare a default paragraph style.'
|
26
26
|
end
|
@@ -30,6 +30,7 @@ module Caracal
|
|
30
30
|
xml.send 'w:rFonts', font_options(s)
|
31
31
|
xml.send 'w:b', { 'w:val' => (s.style_bold ? '1' : '0') }
|
32
32
|
xml.send 'w:i', { 'w:val' => (s.style_italic ? '1' : '0') }
|
33
|
+
xml.send 'w:caps', { 'w:val' => (s.style_caps ? '1' : '0') }
|
33
34
|
xml.send 'w:smallCaps', { 'w:val' => '0' }
|
34
35
|
xml.send 'w:strike', { 'w:val' => '0' }
|
35
36
|
xml.send 'w:color', { 'w:val' => s.style_color }
|
@@ -59,10 +60,10 @@ module Caracal
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
default_id = s.style_id
|
62
|
-
|
63
|
-
|
63
|
+
|
64
|
+
|
64
65
|
#============ PARAGRAPH STYLES ================================
|
65
|
-
|
66
|
+
|
66
67
|
document.styles.reject { |s| s.style_id == default_id }.each do |s|
|
67
68
|
xml.send 'w:style', { 'w:styleId' => s.style_id, 'w:type' => 'paragraph' } do
|
68
69
|
xml.send 'w:name', { 'w:val' => s.style_name }
|
@@ -80,15 +81,16 @@ module Caracal
|
|
80
81
|
xml.send 'w:rFonts', font_options(s) unless s.style_font.nil?
|
81
82
|
xml.send 'w:b', { 'w:val' => (s.style_bold ? '1' : '0') } unless s.style_bold.nil?
|
82
83
|
xml.send 'w:i', { 'w:val' => (s.style_italic ? '1' : '0') } unless s.style_italic.nil?
|
84
|
+
xml.send 'w:caps', { 'w:val' => (s.style_caps ? '1' : '0') } unless s.style_caps.nil?
|
83
85
|
xml.send 'w:color', { 'w:val' => s.style_color } unless s.style_color.nil?
|
84
86
|
xml.send 'w:sz', { 'w:val' => s.style_size } unless s.style_size.nil?
|
85
87
|
xml.send 'w:u', { 'w:val' => (s.style_underline ? 'single' : 'none') } unless s.style_underline.nil?
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
89
|
-
|
91
|
+
|
90
92
|
#============ TABLE STYLES ================================
|
91
|
-
|
93
|
+
|
92
94
|
xml.send 'w:style', { 'w:styleId' => 'DefaultTable', 'w:type' => 'table' } do
|
93
95
|
xml.send 'w:basedOn', { 'w:val' => 'TableNormal' }
|
94
96
|
xml.send 'w:tblPr' do
|
@@ -105,29 +107,29 @@ module Caracal
|
|
105
107
|
xml.send 'w:tblStylePr', { 'w:type' => type }
|
106
108
|
end
|
107
109
|
end
|
108
|
-
|
110
|
+
|
109
111
|
end
|
110
112
|
end
|
111
113
|
builder.to_xml(save_options)
|
112
114
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
115
|
+
|
116
|
+
|
117
|
+
|
116
118
|
#-------------------------------------------------------------
|
117
119
|
# Private Methods
|
118
|
-
#-------------------------------------------------------------
|
120
|
+
#-------------------------------------------------------------
|
119
121
|
private
|
120
|
-
|
122
|
+
|
121
123
|
def font_options(style)
|
122
124
|
name = style.style_font
|
123
125
|
{ 'w:cs' => name, 'w:hAnsi' => name, 'w:eastAsia' => name, 'w:ascii' => name }
|
124
126
|
end
|
125
|
-
|
127
|
+
|
126
128
|
def spacing_options(style, default=false)
|
127
129
|
top = (default) ? style.style_top.to_i : style.style_top
|
128
130
|
bottom = (default) ? style.style_bottom.to_i : style.style_bottom
|
129
131
|
line = style.style_line
|
130
|
-
|
132
|
+
|
131
133
|
options = nil
|
132
134
|
if [top, bottom, line].compact.size > 0
|
133
135
|
options = {}
|
@@ -138,7 +140,7 @@ module Caracal
|
|
138
140
|
end
|
139
141
|
options
|
140
142
|
end
|
141
|
-
|
143
|
+
|
142
144
|
def root_options
|
143
145
|
{
|
144
146
|
'xmlns:mc' => 'http://schemas.openxmlformats.org/markup-compatibility/2006',
|
@@ -158,7 +160,7 @@ module Caracal
|
|
158
160
|
'xmlns:dgm' => 'http://schemas.openxmlformats.org/drawingml/2006/diagram'
|
159
161
|
}
|
160
162
|
end
|
161
|
-
|
163
|
+
|
162
164
|
end
|
163
165
|
end
|
164
|
-
end
|
166
|
+
end
|
data/lib/caracal/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Caracal::Core::Models::StyleModel do
|
4
|
-
subject do
|
4
|
+
subject do
|
5
5
|
described_class.new do
|
6
6
|
id 'Normal'
|
7
7
|
name 'normal'
|
@@ -10,13 +10,13 @@ describe Caracal::Core::Models::StyleModel do
|
|
10
10
|
line 360
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
#-------------------------------------------------------------
|
15
15
|
# Configuration
|
16
16
|
#-------------------------------------------------------------
|
17
17
|
|
18
18
|
describe 'configuration tests' do
|
19
|
-
|
19
|
+
|
20
20
|
# constants
|
21
21
|
describe 'constants' do
|
22
22
|
it { expect(described_class::DEFAULT_STYLE_COLOR).to eq '333333' }
|
@@ -24,6 +24,7 @@ describe Caracal::Core::Models::StyleModel do
|
|
24
24
|
it { expect(described_class::DEFAULT_STYLE_BOLD).to eq false }
|
25
25
|
it { expect(described_class::DEFAULT_STYLE_ITALIC).to eq false }
|
26
26
|
it { expect(described_class::DEFAULT_STYLE_UNDERLINE).to eq false }
|
27
|
+
it { expect(described_class::DEFAULT_STYLE_CAPS).to eq false }
|
27
28
|
it { expect(described_class::DEFAULT_STYLE_ALIGN).to eq :left }
|
28
29
|
it { expect(described_class::DEFAULT_STYLE_TOP).to eq 0 }
|
29
30
|
it { expect(described_class::DEFAULT_STYLE_BOTTOM).to eq 0 }
|
@@ -31,7 +32,7 @@ describe Caracal::Core::Models::StyleModel do
|
|
31
32
|
it { expect(described_class::DEFAULT_STYLE_BASE).to eq 'Normal' }
|
32
33
|
it { expect(described_class::DEFAULT_STYLE_NEXT).to eq 'Normal' }
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
# accessors
|
36
37
|
describe 'accessors' do
|
37
38
|
it { expect(subject.style_default).to eq true }
|
@@ -43,6 +44,7 @@ describe Caracal::Core::Models::StyleModel do
|
|
43
44
|
it { expect(subject.style_bold).to eq false }
|
44
45
|
it { expect(subject.style_italic).to eq false }
|
45
46
|
it { expect(subject.style_underline).to eq false }
|
47
|
+
it { expect(subject.style_caps).to eq false }
|
46
48
|
it { expect(subject.style_align).to eq :left }
|
47
49
|
it { expect(subject.style_top).to eq 0 }
|
48
50
|
it { expect(subject.style_bottom).to eq 0 }
|
@@ -50,106 +52,111 @@ describe Caracal::Core::Models::StyleModel do
|
|
50
52
|
it { expect(subject.style_base).to eq 'Normal' }
|
51
53
|
it { expect(subject.style_next).to eq 'Normal' }
|
52
54
|
end
|
53
|
-
|
55
|
+
|
54
56
|
end
|
55
|
-
|
56
|
-
|
57
|
+
|
58
|
+
|
57
59
|
#-------------------------------------------------------------
|
58
60
|
# Public Methods
|
59
61
|
#-------------------------------------------------------------
|
60
|
-
|
62
|
+
|
61
63
|
describe 'public method tests' do
|
62
|
-
|
64
|
+
|
63
65
|
#=============== SETTERS ==========================
|
64
|
-
|
66
|
+
|
65
67
|
# booleans
|
66
68
|
describe '.bold' do
|
67
69
|
before { subject.bold(true) }
|
68
|
-
|
70
|
+
|
69
71
|
it { expect(subject.style_bold).to eq true }
|
70
72
|
end
|
71
73
|
describe '.italic' do
|
72
74
|
before { subject.italic(true) }
|
73
|
-
|
75
|
+
|
74
76
|
it { expect(subject.style_italic).to eq true }
|
75
77
|
end
|
76
78
|
describe '.underline' do
|
77
79
|
before { subject.underline(true) }
|
78
|
-
|
80
|
+
|
79
81
|
it { expect(subject.style_underline).to eq true }
|
80
82
|
end
|
81
|
-
|
83
|
+
describe '.caps' do
|
84
|
+
before { subject.caps(true) }
|
85
|
+
|
86
|
+
it { expect(subject.style_caps).to eq true }
|
87
|
+
end
|
88
|
+
|
82
89
|
# integers
|
83
90
|
describe '.bottom' do
|
84
91
|
before { subject.bottom(100) }
|
85
|
-
|
92
|
+
|
86
93
|
it { expect(subject.style_bottom).to eq 100 }
|
87
94
|
end
|
88
95
|
describe '.size' do
|
89
96
|
before { subject.size(24) }
|
90
|
-
|
97
|
+
|
91
98
|
it { expect(subject.style_size).to eq 24 }
|
92
99
|
end
|
93
100
|
describe '.line' do
|
94
101
|
before { subject.line(480) }
|
95
|
-
|
102
|
+
|
96
103
|
it { expect(subject.style_line).to eq 480 }
|
97
104
|
end
|
98
105
|
describe '.top' do
|
99
106
|
before { subject.top(100) }
|
100
|
-
|
107
|
+
|
101
108
|
it { expect(subject.style_top).to eq 100 }
|
102
109
|
end
|
103
|
-
|
110
|
+
|
104
111
|
# strings
|
105
112
|
describe '.id' do
|
106
113
|
before { subject.id('heading1') }
|
107
|
-
|
114
|
+
|
108
115
|
it { expect(subject.style_id).to eq 'heading1' }
|
109
116
|
end
|
110
117
|
describe '.name' do
|
111
118
|
before { subject.name('Heading 1') }
|
112
|
-
|
119
|
+
|
113
120
|
it { expect(subject.style_name).to eq 'Heading 1' }
|
114
121
|
end
|
115
122
|
describe '.color' do
|
116
123
|
before { subject.color('444444') }
|
117
|
-
|
124
|
+
|
118
125
|
it { expect(subject.style_color).to eq '444444' }
|
119
126
|
end
|
120
127
|
describe '.font' do
|
121
128
|
before { subject.font('Helvetica') }
|
122
|
-
|
129
|
+
|
123
130
|
it { expect(subject.style_font).to eq 'Helvetica' }
|
124
131
|
end
|
125
|
-
|
132
|
+
|
126
133
|
# symbols
|
127
134
|
describe '.align' do
|
128
135
|
before { subject.align(:right) }
|
129
|
-
|
136
|
+
|
130
137
|
it { expect(subject.style_align).to eq :right }
|
131
138
|
end
|
132
|
-
|
133
|
-
|
139
|
+
|
140
|
+
|
134
141
|
#=================== STATE ===============================
|
135
|
-
|
142
|
+
|
136
143
|
# .matches?
|
137
144
|
describe '.matches?' do
|
138
145
|
describe 'when search term matches' do
|
139
146
|
let(:actual) { subject.matches?('normal') }
|
140
|
-
|
147
|
+
|
141
148
|
it { expect(actual).to eq true }
|
142
149
|
end
|
143
150
|
describe 'when search term does not match' do
|
144
151
|
let(:actual) { subject.matches?('Dummy') }
|
145
|
-
|
152
|
+
|
146
153
|
it { expect(actual).to eq false }
|
147
154
|
end
|
148
155
|
end
|
149
|
-
|
150
|
-
|
156
|
+
|
157
|
+
|
151
158
|
#=============== VALIDATION ===========================
|
152
|
-
|
159
|
+
|
153
160
|
describe '.valid?' do
|
154
161
|
describe 'when type and id provided' do
|
155
162
|
it { expect(subject.valid?).to eq true }
|
@@ -159,29 +166,29 @@ describe Caracal::Core::Models::StyleModel do
|
|
159
166
|
before do
|
160
167
|
allow(subject).to receive("style_#{ prop }").and_return(nil)
|
161
168
|
end
|
162
|
-
|
169
|
+
|
163
170
|
it { expect(subject.valid?).to eq false }
|
164
171
|
end
|
165
172
|
end
|
166
173
|
end
|
167
|
-
|
174
|
+
|
168
175
|
end
|
169
|
-
|
170
|
-
|
176
|
+
|
177
|
+
|
171
178
|
#-------------------------------------------------------------
|
172
179
|
# Private Methods
|
173
180
|
#-------------------------------------------------------------
|
174
|
-
|
181
|
+
|
175
182
|
describe 'private method tests' do
|
176
|
-
|
183
|
+
|
177
184
|
# .option_keys
|
178
185
|
describe '.option_keys' do
|
179
186
|
let(:actual) { subject.send(:option_keys).sort }
|
180
|
-
let(:expected) { [:bold, :italic, :underline, :top, :bottom, :size, :line, :id, :name, :color, :font, :align].sort }
|
181
|
-
|
187
|
+
let(:expected) { [:bold, :italic, :underline, :caps, :top, :bottom, :size, :line, :id, :name, :color, :font, :align].sort }
|
188
|
+
|
182
189
|
it { expect(actual).to eq expected }
|
183
190
|
end
|
184
|
-
|
191
|
+
|
185
192
|
end
|
186
|
-
|
187
|
-
end
|
193
|
+
|
194
|
+
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: 0.2.
|
4
|
+
version: 0.2.1
|
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: 2014-
|
12
|
+
date: 2014-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|