caracal 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +51 -8
- data/lib/caracal/core/models/table_cell_model.rb +21 -11
- data/lib/caracal/core/models/text_model.rb +17 -8
- data/lib/caracal/renderers/document_renderer.rb +9 -7
- data/lib/caracal/version.rb +1 -1
- data/spec/lib/caracal/core/models/table_cell_model_spec.rb +10 -1
- data/spec/lib/caracal/core/models/text_model_spec.rb +18 -10
- 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: 491450be9349f7528fa95e04b379b72f4807d395
|
4
|
+
data.tar.gz: 823708c706f984673a8f42c64d73e5d4fdc9be87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 575e505a4c78d7ffc05b87587d12fa94c436ce53c9d466762a84fa9fdeaca974843cec777698ca2cd1bf1ddea1c0727637275f6d3dcc0b3738a7226e29b93f30
|
7
|
+
data.tar.gz: a91c03e2d61d31db942c1c086b462e2528694533055616bb1ff9f30f0f2026c5a4c4b66262c308830c33abb47878dd97f42c9ba0c4994853edded97c1e2fd855
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -84,6 +84,7 @@ You may not know that .docx files are simply a zipped collection of XML document
|
|
84
84
|
|
85
85
|
For each Caracal request, the following document structure will be created and zipped into the final output file:
|
86
86
|
|
87
|
+
```
|
87
88
|
example.docx
|
88
89
|
|- _rels
|
89
90
|
|- .rels
|
@@ -105,6 +106,7 @@ For each Caracal request, the following document structure will be created and z
|
|
105
106
|
|- settings.xml
|
106
107
|
|- styles.xml
|
107
108
|
|- [Content_Types].xml
|
109
|
+
```
|
108
110
|
|
109
111
|
|
110
112
|
## File Descriptions
|
@@ -386,14 +388,15 @@ docx.p 'Sample text.'
|
|
386
388
|
docx.p 'Sample text.', style: 'custom_style'
|
387
389
|
|
388
390
|
docx.p 'Sample text.' do
|
389
|
-
style
|
390
|
-
align
|
391
|
-
color
|
392
|
-
size
|
393
|
-
bold
|
394
|
-
italic
|
395
|
-
underline
|
396
|
-
bgcolor
|
391
|
+
style 'custom_style' # sets the paragraph style. generally used at the exclusion of other attributes.
|
392
|
+
align :left # sets the alignment. accepts :left, :center, :right, and :both.
|
393
|
+
color '333333' # sets the font color.
|
394
|
+
size 32 # sets the font size. units in 1/2 points.
|
395
|
+
bold true # sets whether or not to render the text with a bold weight.
|
396
|
+
italic false # sets whether or not render the text in italic style.
|
397
|
+
underline false # sets whether or not to underline the text.
|
398
|
+
bgcolor 'cccccc' # sets the background color.
|
399
|
+
vertical_align 'superscript' # sets the vertical alignment.
|
397
400
|
end
|
398
401
|
```
|
399
402
|
|
@@ -675,6 +678,46 @@ Caracal includes [Tilt](https://github.com/rtomayko/tilt) integration to facilit
|
|
675
678
|
Rails integration can be added via the [Caracal-Rails](https://github.com/trade-informatics/caracal-rails) gem.
|
676
679
|
|
677
680
|
|
681
|
+
## Filing an Issue
|
682
|
+
|
683
|
+
Caracal was written for and tested against Word 2010, 2013, and Office365. It should also open in LibreOffice
|
684
|
+
with high fidelity.
|
685
|
+
|
686
|
+
### Older Versions
|
687
|
+
If you are using a version of Word that predates 2010, Caracal may or may not work for you. (Probably it won't.)
|
688
|
+
We don't ever plan to support versions before 2010, but if you choose to embark on that endeavor, we'd be
|
689
|
+
happy to answer questions and provide what guidance we can. We just won't write any code in that direction.
|
690
|
+
|
691
|
+
### Newer Versions
|
692
|
+
|
693
|
+
For those using reasonably current versions of Word, please consider the following:
|
694
|
+
|
695
|
+
- Before you file an issue, please run the example Caracal project [caracal-example](https://github.com/trade-informatics/caracal-example) in your development environment and
|
696
|
+
check the output. This project implements nearly every feature Caracal supports and renders the expected output
|
697
|
+
correctly. It can be thought of as a canonical implementation of the library.
|
698
|
+
|
699
|
+
- If you don't see your issue in the example project's implementation of the same feature, chances are you
|
700
|
+
made a mistake in your document's syntax or have an environment-specific, non-caracal problem.
|
701
|
+
|
702
|
+
- If you do see the same behavior in the example project, you've probably uncovered a variance in the way
|
703
|
+
your particular permutation of Windows/Word interprets the OOXML.
|
704
|
+
|
705
|
+
### How to Work on a Problem
|
706
|
+
|
707
|
+
Caracal is essentially an exercise in reverse engineering OOXML output. When developing features, we
|
708
|
+
typically start by building the simplest Word document we can that includes the desired behavior.
|
709
|
+
Then, we change the document extension to .zip, extract the archive, and inspect the resulting OOXML.
|
710
|
+
Finally, we teach the corresponding renderer to output that OOXML.
|
711
|
+
|
712
|
+
It's a tedious process, but it's not nearly as tedious as learning the entire OOXML specification.
|
713
|
+
|
714
|
+
The downside is Word changes its expectations about OOXML format with each version, so it can be a bit
|
715
|
+
of a balancing act to get the OOXML structured for acceptance by all supported versions.
|
716
|
+
|
717
|
+
Ultimately, we'll probably need to implement version-specific renderers (i.e., a set of renderers
|
718
|
+
for 2010/2013, a set for 2016, etc.).
|
719
|
+
|
720
|
+
|
678
721
|
## Contributing
|
679
722
|
|
680
723
|
1. Fork it ( https://github.com/trade-informatics/caracal/fork )
|
@@ -16,19 +16,22 @@ module Caracal
|
|
16
16
|
#-------------------------------------------------------------
|
17
17
|
|
18
18
|
# constants
|
19
|
-
const_set(:DEFAULT_CELL_BACKGROUND,
|
20
|
-
const_set(:DEFAULT_CELL_MARGINS,
|
21
|
-
|
19
|
+
const_set(:DEFAULT_CELL_BACKGROUND, 'ffffff')
|
20
|
+
const_set(:DEFAULT_CELL_MARGINS, Caracal::Core::Models::MarginModel.new({ top: 100, bottom: 100, left: 100, right: 100 }))
|
21
|
+
const_set(:DEFAULT_CELL_VERTICAL_ALIGN, :top)
|
22
|
+
|
22
23
|
# accessors
|
23
24
|
attr_reader :cell_background
|
24
25
|
attr_reader :cell_width
|
25
26
|
attr_reader :cell_margins
|
26
|
-
|
27
|
+
attr_reader :cell_vertical_align
|
28
|
+
|
27
29
|
# initialization
|
28
30
|
def initialize(options={}, &block)
|
29
|
-
@cell_background
|
30
|
-
@cell_margins
|
31
|
-
|
31
|
+
@cell_background = DEFAULT_CELL_BACKGROUND
|
32
|
+
@cell_margins = DEFAULT_CELL_MARGINS
|
33
|
+
@cell_vertical_align = DEFAULT_CELL_VERTICAL_ALIGN
|
34
|
+
|
32
35
|
if content = options.delete(:content)
|
33
36
|
p content, options.dup
|
34
37
|
end
|
@@ -134,8 +137,15 @@ module Caracal
|
|
134
137
|
instance_variable_set("@cell_#{ m }", value.to_s)
|
135
138
|
end
|
136
139
|
end
|
137
|
-
|
138
|
-
|
140
|
+
|
141
|
+
#symbols
|
142
|
+
[:vertical_align].each do |m|
|
143
|
+
define_method "#{ m }" do |value|
|
144
|
+
instance_variable_set("@cell_#{ m }", value.to_s.to_sym)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
139
149
|
#=============== VALIDATION ===========================
|
140
150
|
|
141
151
|
def valid?
|
@@ -149,11 +159,11 @@ module Caracal
|
|
149
159
|
private
|
150
160
|
|
151
161
|
def option_keys
|
152
|
-
[:background, :margins, :width]
|
162
|
+
[:background, :margins, :width, :vertical_align]
|
153
163
|
end
|
154
164
|
|
155
165
|
end
|
156
166
|
|
157
167
|
end
|
158
168
|
end
|
159
|
-
end
|
169
|
+
end
|
@@ -23,6 +23,7 @@ module Caracal
|
|
23
23
|
attr_reader :text_italic
|
24
24
|
attr_reader :text_underline
|
25
25
|
attr_reader :text_bgcolor
|
26
|
+
attr_reader :text_vertical_align
|
26
27
|
|
27
28
|
|
28
29
|
|
@@ -35,13 +36,14 @@ module Caracal
|
|
35
36
|
# .run_attributes
|
36
37
|
def run_attributes
|
37
38
|
{
|
38
|
-
font:
|
39
|
-
color:
|
40
|
-
size:
|
41
|
-
bold:
|
42
|
-
italic:
|
43
|
-
underline:
|
44
|
-
bgcolor:
|
39
|
+
font: text_font,
|
40
|
+
color: text_color,
|
41
|
+
size: text_size,
|
42
|
+
bold: text_bold,
|
43
|
+
italic: text_italic,
|
44
|
+
underline: text_underline,
|
45
|
+
bgcolor: text_bgcolor,
|
46
|
+
vertical_align: text_vertical_align
|
45
47
|
}
|
46
48
|
end
|
47
49
|
|
@@ -69,6 +71,13 @@ module Caracal
|
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
74
|
+
# symbols
|
75
|
+
[:vertical_align].each do |m|
|
76
|
+
define_method "#{ m }" do |value|
|
77
|
+
instance_variable_set("@text_#{ m }", value.to_s.to_sym)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
72
81
|
|
73
82
|
#=============== VALIDATION ===========================
|
74
83
|
|
@@ -84,7 +93,7 @@ module Caracal
|
|
84
93
|
private
|
85
94
|
|
86
95
|
def option_keys
|
87
|
-
[:content, :font, :color, :size, :bold, :italic, :underline, :bgcolor]
|
96
|
+
[:content, :font, :color, :size, :bold, :italic, :underline, :bgcolor, :vertical_align]
|
88
97
|
end
|
89
98
|
|
90
99
|
end
|
@@ -75,13 +75,14 @@ module Caracal
|
|
75
75
|
else
|
76
76
|
xml.send 'w:rPr' do
|
77
77
|
unless attrs.empty?
|
78
|
-
xml.send 'w:rStyle',
|
79
|
-
xml.send 'w:color',
|
80
|
-
xml.send 'w:sz',
|
81
|
-
xml.send 'w:b',
|
82
|
-
xml.send 'w:i',
|
83
|
-
xml.send 'w:u',
|
84
|
-
xml.send 'w:shd',
|
78
|
+
xml.send 'w:rStyle', { 'w:val' => attrs[:style] } unless attrs[:style].nil?
|
79
|
+
xml.send 'w:color', { 'w:val' => attrs[:color] } unless attrs[:color].nil?
|
80
|
+
xml.send 'w:sz', { 'w:val' => attrs[:size] } unless attrs[:size].nil?
|
81
|
+
xml.send 'w:b', { 'w:val' => (attrs[:bold] ? '1' : '0') } unless attrs[:bold].nil?
|
82
|
+
xml.send 'w:i', { 'w:val' => (attrs[:italic] ? '1' : '0') } unless attrs[:italic].nil?
|
83
|
+
xml.send 'w:u', { 'w:val' => (attrs[:underline] ? 'single' : 'none') } unless attrs[:underline].nil?
|
84
|
+
xml.send 'w:shd', { 'w:fill' => attrs[:bgcolor], 'w:val' => 'clear' } unless attrs[:bgcolor].nil?
|
85
|
+
xml.send 'w:vertAlign', { 'w:val' => attrs[:vertical_align] } unless attrs[:vertical_align].nil?
|
85
86
|
unless attrs[:font].nil?
|
86
87
|
f = attrs[:font]
|
87
88
|
xml.send 'w:rFonts', { 'w:ascii' => f, 'w:hAnsi' => f, 'w:eastAsia' => f, 'w:cs' => f }
|
@@ -300,6 +301,7 @@ module Caracal
|
|
300
301
|
xml.send 'w:tc' do
|
301
302
|
xml.send 'tcPr' do
|
302
303
|
xml.send 'w:shd', { 'w:fill' => tc.cell_background }
|
304
|
+
xml.send 'w:vAlign', { 'w:val' => tc.cell_vertical_align }
|
303
305
|
xml.send 'w:tcMar' do
|
304
306
|
%w(top left bottom right).each do |d|
|
305
307
|
xml.send "w:#{ d }", { 'w:w' => tc.send("cell_margin_#{ d }").to_f, 'w:type' => 'dxa' }
|
data/lib/caracal/version.rb
CHANGED
@@ -23,6 +23,7 @@ describe Caracal::Core::Models::TableCellModel do
|
|
23
23
|
# constants
|
24
24
|
describe 'constants' do
|
25
25
|
it { expect(described_class::DEFAULT_CELL_BACKGROUND).to eq 'ffffff' }
|
26
|
+
it { expect(described_class::DEFAULT_CELL_VERTICAL_ALIGN).to eq :top }
|
26
27
|
it { expect(described_class::DEFAULT_CELL_MARGINS).to be_a(Caracal::Core::Models::MarginModel) }
|
27
28
|
it { expect(described_class::DEFAULT_CELL_MARGINS.margin_top).to eq 100 }
|
28
29
|
it { expect(described_class::DEFAULT_CELL_MARGINS.margin_bottom).to eq 100 }
|
@@ -35,6 +36,7 @@ describe Caracal::Core::Models::TableCellModel do
|
|
35
36
|
it { expect(subject.cell_background).to eq 'cccccc' }
|
36
37
|
it { expect(subject.cell_margins).to be_a(Caracal::Core::Models::MarginModel) }
|
37
38
|
it { expect(subject.cell_width).to eq 2000 }
|
39
|
+
it { expect(subject.cell_vertical_align).to eq :top }
|
38
40
|
end
|
39
41
|
|
40
42
|
end
|
@@ -95,6 +97,13 @@ describe Caracal::Core::Models::TableCellModel do
|
|
95
97
|
|
96
98
|
it { expect(subject.cell_width).to eq 7500 }
|
97
99
|
end
|
100
|
+
|
101
|
+
#.vertical_allign
|
102
|
+
describe '.vertical_align' do
|
103
|
+
before { subject.vertical_align(:center) }
|
104
|
+
|
105
|
+
it { expect(subject.cell_vertical_align).to eq :center }
|
106
|
+
end
|
98
107
|
|
99
108
|
|
100
109
|
#=============== CONTENT FNS =======================
|
@@ -211,7 +220,7 @@ describe Caracal::Core::Models::TableCellModel do
|
|
211
220
|
# .option_keys
|
212
221
|
describe '.option_keys' do
|
213
222
|
let(:actual) { subject.send(:option_keys).sort }
|
214
|
-
let(:expected) { [:background, :width, :margins].sort }
|
223
|
+
let(:expected) { [:background, :width, :vertical_align, :margins].sort }
|
215
224
|
|
216
225
|
it { expect(actual).to eq expected }
|
217
226
|
end
|
@@ -3,14 +3,15 @@ require 'spec_helper'
|
|
3
3
|
describe Caracal::Core::Models::TextModel do
|
4
4
|
subject do
|
5
5
|
described_class.new do
|
6
|
-
content
|
7
|
-
font
|
8
|
-
color
|
9
|
-
size
|
10
|
-
bold
|
11
|
-
italic
|
12
|
-
underline
|
13
|
-
bgcolor
|
6
|
+
content 'Lorem ipsum dolor....'
|
7
|
+
font 'Courier New'
|
8
|
+
color '666666'
|
9
|
+
size 20
|
10
|
+
bold false
|
11
|
+
italic false
|
12
|
+
underline true
|
13
|
+
bgcolor 'cccccc'
|
14
|
+
vertical_align :subscript
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -30,6 +31,7 @@ describe Caracal::Core::Models::TextModel do
|
|
30
31
|
it { expect(subject.text_italic).to eq false }
|
31
32
|
it { expect(subject.text_underline).to eq true }
|
32
33
|
it { expect(subject.text_bgcolor).to eq 'cccccc' }
|
34
|
+
it { expect(subject.text_vertical_align).to eq :subscript }
|
33
35
|
end
|
34
36
|
|
35
37
|
end
|
@@ -45,7 +47,7 @@ describe Caracal::Core::Models::TextModel do
|
|
45
47
|
|
46
48
|
# .run_attributes
|
47
49
|
describe '.run_attributes' do
|
48
|
-
let(:expected) { { font: 'Courier New', color: '666666', size: 20, bold: false, italic: false, underline: true, bgcolor: 'cccccc' } }
|
50
|
+
let(:expected) { { font: 'Courier New', color: '666666', size: 20, bold: false, italic: false, underline: true, bgcolor: 'cccccc', vertical_align: :subscript } }
|
49
51
|
|
50
52
|
it { expect(subject.run_attributes).to eq expected }
|
51
53
|
end
|
@@ -99,6 +101,12 @@ describe Caracal::Core::Models::TextModel do
|
|
99
101
|
it { expect(subject.text_font).to eq 'Palantino' }
|
100
102
|
end
|
101
103
|
|
104
|
+
#symbols
|
105
|
+
describe '.vertical_align' do
|
106
|
+
before { subject.vertical_align(:superscript) }
|
107
|
+
|
108
|
+
it { expect(subject.text_vertical_align).to eq :superscript }
|
109
|
+
end
|
102
110
|
|
103
111
|
#=============== VALIDATION ===========================
|
104
112
|
|
@@ -129,7 +137,7 @@ describe Caracal::Core::Models::TextModel do
|
|
129
137
|
# .option_keys
|
130
138
|
describe '.option_keys' do
|
131
139
|
let(:actual) { subject.send(:option_keys).sort }
|
132
|
-
let(:expected) { [:bgcolor, :bold, :color, :content, :font, :italic, :size, :underline].sort }
|
140
|
+
let(:expected) { [:bgcolor, :bold, :color, :content, :font, :italic, :size, :underline, :vertical_align].sort }
|
133
141
|
|
134
142
|
it { expect(actual).to eq expected }
|
135
143
|
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.
|
4
|
+
version: 1.0.5
|
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: 2016-
|
12
|
+
date: 2016-05-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|