caracal_the_curve 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +22 -0
- data/.github/workflows/publish_gem.yml +40 -0
- data/.gitignore +25 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +141 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +842 -0
- data/Rakefile +7 -0
- data/caracal.gemspec +28 -0
- data/lib/caracal/core/bookmarks.rb +52 -0
- data/lib/caracal/core/custom_properties.rb +49 -0
- data/lib/caracal/core/file_name.rb +43 -0
- data/lib/caracal/core/fonts.rb +75 -0
- data/lib/caracal/core/iframes.rb +42 -0
- data/lib/caracal/core/ignorables.rb +47 -0
- data/lib/caracal/core/images.rb +37 -0
- data/lib/caracal/core/list_styles.rb +93 -0
- data/lib/caracal/core/lists.rb +57 -0
- data/lib/caracal/core/models/base_model.rb +51 -0
- data/lib/caracal/core/models/bookmark_model.rb +86 -0
- data/lib/caracal/core/models/border_model.rb +120 -0
- data/lib/caracal/core/models/custom_property_model.rb +60 -0
- data/lib/caracal/core/models/font_model.rb +64 -0
- data/lib/caracal/core/models/iframe_model.rb +148 -0
- data/lib/caracal/core/models/image_model.rb +133 -0
- data/lib/caracal/core/models/line_break_model.rb +15 -0
- data/lib/caracal/core/models/link_model.rb +94 -0
- data/lib/caracal/core/models/list_item_model.rb +108 -0
- data/lib/caracal/core/models/list_model.rb +132 -0
- data/lib/caracal/core/models/list_style_model.rb +118 -0
- data/lib/caracal/core/models/margin_model.rb +76 -0
- data/lib/caracal/core/models/namespace_model.rb +65 -0
- data/lib/caracal/core/models/page_break_model.rb +61 -0
- data/lib/caracal/core/models/page_number_model.rb +95 -0
- data/lib/caracal/core/models/page_size_model.rb +79 -0
- data/lib/caracal/core/models/paragraph_model.rb +186 -0
- data/lib/caracal/core/models/relationship_model.rb +114 -0
- data/lib/caracal/core/models/rule_model.rb +27 -0
- data/lib/caracal/core/models/style_model.rb +165 -0
- data/lib/caracal/core/models/table_cell_model.rb +176 -0
- data/lib/caracal/core/models/table_model.rb +206 -0
- data/lib/caracal/core/models/text_model.rb +118 -0
- data/lib/caracal/core/namespaces.rb +89 -0
- data/lib/caracal/core/page_breaks.rb +29 -0
- data/lib/caracal/core/page_numbers.rb +58 -0
- data/lib/caracal/core/page_settings.rb +74 -0
- data/lib/caracal/core/relationships.rb +90 -0
- data/lib/caracal/core/rules.rb +35 -0
- data/lib/caracal/core/styles.rb +86 -0
- data/lib/caracal/core/tables.rb +42 -0
- data/lib/caracal/core/text.rb +75 -0
- data/lib/caracal/document.rb +272 -0
- data/lib/caracal/errors.rb +23 -0
- data/lib/caracal/renderers/app_renderer.rb +41 -0
- data/lib/caracal/renderers/content_types_renderer.rb +54 -0
- data/lib/caracal/renderers/core_renderer.rb +44 -0
- data/lib/caracal/renderers/custom_renderer.rb +64 -0
- data/lib/caracal/renderers/document_renderer.rb +427 -0
- data/lib/caracal/renderers/fonts_renderer.rb +56 -0
- data/lib/caracal/renderers/footer_renderer.rb +90 -0
- data/lib/caracal/renderers/numbering_renderer.rb +88 -0
- data/lib/caracal/renderers/package_relationships_renderer.rb +51 -0
- data/lib/caracal/renderers/relationships_renderer.rb +48 -0
- data/lib/caracal/renderers/settings_renderer.rb +58 -0
- data/lib/caracal/renderers/styles_renderer.rb +181 -0
- data/lib/caracal/renderers/xml_renderer.rb +83 -0
- data/lib/caracal/utilities.rb +23 -0
- data/lib/caracal/version.rb +3 -0
- data/lib/caracal.rb +40 -0
- data/lib/tilt/caracal.rb +21 -0
- data/spec/lib/caracal/core/bookmarks_spec.rb +35 -0
- data/spec/lib/caracal/core/file_name_spec.rb +54 -0
- data/spec/lib/caracal/core/fonts_spec.rb +119 -0
- data/spec/lib/caracal/core/iframes_spec.rb +29 -0
- data/spec/lib/caracal/core/ignorables_spec.rb +79 -0
- data/spec/lib/caracal/core/images_spec.rb +25 -0
- data/spec/lib/caracal/core/list_styles_spec.rb +121 -0
- data/spec/lib/caracal/core/lists_spec.rb +43 -0
- data/spec/lib/caracal/core/models/base_model_spec.rb +38 -0
- data/spec/lib/caracal/core/models/bookmark_model_spec.rb +135 -0
- data/spec/lib/caracal/core/models/border_model_spec.rb +159 -0
- data/spec/lib/caracal/core/models/font_model_spec.rb +92 -0
- data/spec/lib/caracal/core/models/iframe_model_spec.rb +83 -0
- data/spec/lib/caracal/core/models/image_model_spec.rb +225 -0
- data/spec/lib/caracal/core/models/line_break_model_spec.rb +21 -0
- data/spec/lib/caracal/core/models/link_model_spec.rb +179 -0
- data/spec/lib/caracal/core/models/list_item_model_spec.rb +197 -0
- data/spec/lib/caracal/core/models/list_model_spec.rb +178 -0
- data/spec/lib/caracal/core/models/list_style_model_spec.rb +198 -0
- data/spec/lib/caracal/core/models/margin_model_spec.rb +111 -0
- data/spec/lib/caracal/core/models/namespace_model_spec.rb +107 -0
- data/spec/lib/caracal/core/models/page_break_model_spec.rb +21 -0
- data/spec/lib/caracal/core/models/page_number_model_spec.rb +136 -0
- data/spec/lib/caracal/core/models/page_size_model_spec.rb +101 -0
- data/spec/lib/caracal/core/models/paragraph_model_spec.rb +196 -0
- data/spec/lib/caracal/core/models/relationship_model_spec.rb +193 -0
- data/spec/lib/caracal/core/models/rule_model_spec.rb +108 -0
- data/spec/lib/caracal/core/models/style_model_spec.rb +225 -0
- data/spec/lib/caracal/core/models/table_cell_model_spec.rb +230 -0
- data/spec/lib/caracal/core/models/table_model_spec.rb +222 -0
- data/spec/lib/caracal/core/models/text_model_spec.rb +154 -0
- data/spec/lib/caracal/core/namespaces_spec.rb +116 -0
- data/spec/lib/caracal/core/page_breaks_spec.rb +25 -0
- data/spec/lib/caracal/core/page_numbers_spec.rb +89 -0
- data/spec/lib/caracal/core/page_settings_spec.rb +151 -0
- data/spec/lib/caracal/core/relationships_spec.rb +119 -0
- data/spec/lib/caracal/core/rules_spec.rb +25 -0
- data/spec/lib/caracal/core/styles_spec.rb +129 -0
- data/spec/lib/caracal/core/tables_spec.rb +25 -0
- data/spec/lib/caracal/core/text_spec.rb +52 -0
- data/spec/lib/caracal/errors_spec.rb +10 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/_fixtures/snippet.docx +0 -0
- metadata +292 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'caracal/core/models/base_model'
|
2
|
+
|
3
|
+
|
4
|
+
module Caracal
|
5
|
+
module Core
|
6
|
+
module Models
|
7
|
+
|
8
|
+
# This class handles block options passed to the page margins
|
9
|
+
# method.
|
10
|
+
#
|
11
|
+
class BorderModel < BaseModel
|
12
|
+
|
13
|
+
#-------------------------------------------------------------
|
14
|
+
# Configuration
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
|
17
|
+
# constants
|
18
|
+
const_set(:DEFAULT_BORDER_COLOR, 'auto')
|
19
|
+
const_set(:DEFAULT_BORDER_LINE, :single)
|
20
|
+
const_set(:DEFAULT_BORDER_SIZE, 4) # 0.5pt in 1/8 points
|
21
|
+
const_set(:DEFAULT_BORDER_SPACING, 1) # 0.125pt in 1/8 points
|
22
|
+
const_set(:DEFAULT_BORDER_TYPE, :top)
|
23
|
+
|
24
|
+
# accessors
|
25
|
+
attr_reader :border_color
|
26
|
+
attr_reader :border_line
|
27
|
+
attr_reader :border_size
|
28
|
+
attr_reader :border_spacing
|
29
|
+
attr_reader :border_type
|
30
|
+
|
31
|
+
# initialization
|
32
|
+
def initialize(options={}, &block)
|
33
|
+
@border_color = DEFAULT_BORDER_COLOR
|
34
|
+
@border_line = DEFAULT_BORDER_LINE
|
35
|
+
@border_size = DEFAULT_BORDER_SIZE
|
36
|
+
@border_spacing = DEFAULT_BORDER_SPACING
|
37
|
+
@border_type = DEFAULT_BORDER_TYPE
|
38
|
+
|
39
|
+
super options, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#-------------------------------------------------------------
|
44
|
+
# Class Methods
|
45
|
+
#-------------------------------------------------------------
|
46
|
+
|
47
|
+
def self.formatted_type(type)
|
48
|
+
case type.to_s.to_sym
|
49
|
+
when :horizontal then 'insideH'
|
50
|
+
when :vertical then 'insideV'
|
51
|
+
when :top then 'top'
|
52
|
+
when :bottom then 'bottom'
|
53
|
+
when :left then 'left'
|
54
|
+
when :right then 'right'
|
55
|
+
else nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
#-------------------------------------------------------------
|
61
|
+
# Public Methods
|
62
|
+
#-------------------------------------------------------------
|
63
|
+
|
64
|
+
#=============== GETTERS ==============================
|
65
|
+
|
66
|
+
def formatted_type
|
67
|
+
self.class.formatted_type(border_type)
|
68
|
+
end
|
69
|
+
|
70
|
+
def total_size
|
71
|
+
border_size + (2 * border_spacing)
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
#=============== SETTERS ==============================
|
76
|
+
|
77
|
+
# integers
|
78
|
+
[:size, :spacing].each do |m|
|
79
|
+
define_method "#{ m }" do |value|
|
80
|
+
instance_variable_set("@border_#{ m }", value.to_i)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# strings
|
85
|
+
[:color].each do |m|
|
86
|
+
define_method "#{ m }" do |value|
|
87
|
+
instance_variable_set("@border_#{ m }", value.to_s)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# symbols
|
92
|
+
[:line, :type].each do |m|
|
93
|
+
define_method "#{ m }" do |value|
|
94
|
+
instance_variable_set("@border_#{ m }", value.to_s.to_sym)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
#=============== VALIDATION ==============================
|
100
|
+
|
101
|
+
def valid?
|
102
|
+
dims = [border_size, border_spacing]
|
103
|
+
dims.all? { |d| d > 0 }
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
#-------------------------------------------------------------
|
108
|
+
# Private Instance Methods
|
109
|
+
#-------------------------------------------------------------
|
110
|
+
private
|
111
|
+
|
112
|
+
def option_keys
|
113
|
+
[:color, :line, :size, :spacing, :type]
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
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
|
@@ -0,0 +1,64 @@
|
|
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
|
+
# font data.
|
10
|
+
#
|
11
|
+
class FontModel < BaseModel
|
12
|
+
|
13
|
+
#-------------------------------------------------------------
|
14
|
+
# Configuration
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
|
17
|
+
# accessors
|
18
|
+
attr_reader :font_name
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
#-------------------------------------------------------------
|
23
|
+
# Public Instance Methods
|
24
|
+
#-------------------------------------------------------------
|
25
|
+
|
26
|
+
#=============== SETTERS ==============================
|
27
|
+
|
28
|
+
# strings
|
29
|
+
[:name].each do |m|
|
30
|
+
define_method "#{ m }" do |value|
|
31
|
+
instance_variable_set("@font_#{ m }", value.to_s)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
#=============== STATE ================================
|
37
|
+
|
38
|
+
def matches?(str)
|
39
|
+
font_name.to_s.downcase == str.to_s.downcase
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#=============== VALIDATION ===========================
|
44
|
+
|
45
|
+
def valid?
|
46
|
+
a = [:name]
|
47
|
+
a.map { |m| send("font_#{ m }") }.compact.size == a.size
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
#-------------------------------------------------------------
|
52
|
+
# Private Instance Methods
|
53
|
+
#-------------------------------------------------------------
|
54
|
+
private
|
55
|
+
|
56
|
+
def option_keys
|
57
|
+
[:name]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'caracal/core/models/base_model'
|
2
|
+
|
3
|
+
module Caracal
|
4
|
+
module Core
|
5
|
+
module Models
|
6
|
+
|
7
|
+
# This class handles block options passed to the img method.
|
8
|
+
#
|
9
|
+
class IFrameModel < BaseModel
|
10
|
+
|
11
|
+
#--------------------------------------------------
|
12
|
+
# Configuration
|
13
|
+
#--------------------------------------------------
|
14
|
+
|
15
|
+
# accessors
|
16
|
+
attr_reader :iframe_url
|
17
|
+
attr_reader :iframe_data
|
18
|
+
attr_reader :iframe_ignorables
|
19
|
+
attr_reader :iframe_namespaces
|
20
|
+
attr_reader :iframe_relationships
|
21
|
+
|
22
|
+
# initialization
|
23
|
+
def initialize(options={}, &block)
|
24
|
+
super options, &block
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
#--------------------------------------------------
|
29
|
+
# Public Methods
|
30
|
+
#--------------------------------------------------
|
31
|
+
|
32
|
+
#=============== PROCESSING =======================
|
33
|
+
|
34
|
+
def preprocess!
|
35
|
+
::Zip::File.open(file) do |zip|
|
36
|
+
# locate relationships xml
|
37
|
+
entry = zip.glob('word/_rels/document.xml.rels').first
|
38
|
+
content = entry.get_input_stream.read
|
39
|
+
rel_xml = Nokogiri::XML(content)
|
40
|
+
|
41
|
+
# locate document xml
|
42
|
+
entry = zip.glob('word/document.xml').first
|
43
|
+
content = entry.get_input_stream.read
|
44
|
+
doc_xml = Nokogiri::XML(content)
|
45
|
+
|
46
|
+
# master nodesets
|
47
|
+
rel_nodes = rel_xml.children.first.children
|
48
|
+
doc_root = doc_xml.at_xpath('//w:document')
|
49
|
+
pic_nodes = doc_xml.xpath('//pic:pic', { pic: 'http://schemas.openxmlformats.org/drawingml/2006/picture' })
|
50
|
+
|
51
|
+
# namespaces
|
52
|
+
@iframe_namespaces = doc_root.namespaces
|
53
|
+
|
54
|
+
# ignorable namespaces
|
55
|
+
if a = doc_root.attributes['Ignorable']
|
56
|
+
@iframe_ignorables = a.value.split(/\s+/)
|
57
|
+
end
|
58
|
+
|
59
|
+
# relationships
|
60
|
+
media_map = rel_nodes.reduce({}) do |hash, node|
|
61
|
+
type = node.at_xpath('@Type').value
|
62
|
+
if type.slice(-5, 5) == 'image'
|
63
|
+
id = node.at_xpath('@Id').value
|
64
|
+
path = "word/#{ node.at_xpath('@Target').value }"
|
65
|
+
hash[id] = path
|
66
|
+
end
|
67
|
+
hash
|
68
|
+
end
|
69
|
+
@iframe_relationships = pic_nodes.reduce([]) do |array, node|
|
70
|
+
r_node = node.children[1].children[0]
|
71
|
+
r_id = r_node.attributes['embed'].value.to_s
|
72
|
+
r_media = media_map[r_id]
|
73
|
+
|
74
|
+
p_node = node.children[0].children[0]
|
75
|
+
p_id = p_node.attributes['id'].to_s.to_i
|
76
|
+
p_name = p_node.attributes['name'].to_s
|
77
|
+
p_data = zip.glob(r_media).first.get_input_stream.read
|
78
|
+
|
79
|
+
# register relationship
|
80
|
+
array << { id: r_id, type: 'image', target: p_name, data: p_data }
|
81
|
+
array
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
#=============== GETTERS ==========================
|
88
|
+
|
89
|
+
def file
|
90
|
+
@file ||= begin
|
91
|
+
if iframe_url.nil?
|
92
|
+
file = Tempfile.new('iframe')
|
93
|
+
file.write iframe_data
|
94
|
+
file.rewind
|
95
|
+
else
|
96
|
+
file = open(iframe_url)
|
97
|
+
end
|
98
|
+
file
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def ignorables
|
103
|
+
@iframe_ignorables || []
|
104
|
+
end
|
105
|
+
|
106
|
+
def namespaces
|
107
|
+
@iframe_namespaces || {}
|
108
|
+
end
|
109
|
+
|
110
|
+
def relationships
|
111
|
+
@iframe_relationships || []
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
#=============== SETTERS ==========================
|
116
|
+
|
117
|
+
# strings
|
118
|
+
[:data, :url].each do |m|
|
119
|
+
define_method "#{ m }" do |value|
|
120
|
+
instance_variable_set("@iframe_#{ m }", value.to_s)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
#=============== VALIDATION =======================
|
126
|
+
|
127
|
+
def valid?
|
128
|
+
vals = option_keys.map { |m| send("iframe_#{ m }") }.compact
|
129
|
+
vals = vals.reject { |v| v.size == 0 }
|
130
|
+
vals.size > 0
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
#--------------------------------------------------
|
136
|
+
# Private Methods
|
137
|
+
#--------------------------------------------------
|
138
|
+
private
|
139
|
+
|
140
|
+
def option_keys
|
141
|
+
[:url, :data]
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'caracal/core/models/base_model'
|
2
|
+
|
3
|
+
|
4
|
+
module Caracal
|
5
|
+
module Core
|
6
|
+
module Models
|
7
|
+
|
8
|
+
# This class handles block options passed to the img method.
|
9
|
+
#
|
10
|
+
class ImageModel < BaseModel
|
11
|
+
|
12
|
+
#-------------------------------------------------------------
|
13
|
+
# Configuration
|
14
|
+
#-------------------------------------------------------------
|
15
|
+
|
16
|
+
# constants
|
17
|
+
const_set(:DEFAULT_IMAGE_PPI, 72) # pixels per inch
|
18
|
+
const_set(:DEFAULT_IMAGE_WIDTH, 0) # units in pixels. (will cause error)
|
19
|
+
const_set(:DEFAULT_IMAGE_HEIGHT, 0) # units in pixels. (will cause error)
|
20
|
+
const_set(:DEFAULT_IMAGE_ALIGN, :left)
|
21
|
+
const_set(:DEFAULT_IMAGE_TOP, 8) # units in pixels.
|
22
|
+
const_set(:DEFAULT_IMAGE_BOTTOM, 8) # units in pixels.
|
23
|
+
const_set(:DEFAULT_IMAGE_LEFT, 8) # units in pixels.
|
24
|
+
const_set(:DEFAULT_IMAGE_RIGHT, 8) # units in pixels.
|
25
|
+
|
26
|
+
# accessors
|
27
|
+
attr_reader :image_url
|
28
|
+
attr_reader :image_data
|
29
|
+
attr_reader :image_ppi
|
30
|
+
attr_reader :image_width
|
31
|
+
attr_reader :image_height
|
32
|
+
attr_reader :image_align
|
33
|
+
attr_reader :image_top
|
34
|
+
attr_reader :image_bottom
|
35
|
+
attr_reader :image_left
|
36
|
+
attr_reader :image_right
|
37
|
+
|
38
|
+
|
39
|
+
# initialization
|
40
|
+
def initialize(options={}, &block)
|
41
|
+
@image_ppi = DEFAULT_IMAGE_PPI
|
42
|
+
@image_width = DEFAULT_IMAGE_WIDTH
|
43
|
+
@image_height = DEFAULT_IMAGE_HEIGHT
|
44
|
+
@image_align = DEFAULT_IMAGE_ALIGN
|
45
|
+
@image_top = DEFAULT_IMAGE_TOP
|
46
|
+
@image_bottom = DEFAULT_IMAGE_BOTTOM
|
47
|
+
@image_left = DEFAULT_IMAGE_LEFT
|
48
|
+
@image_right = DEFAULT_IMAGE_RIGHT
|
49
|
+
|
50
|
+
super options, &block
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
#-------------------------------------------------------------
|
55
|
+
# Public Methods
|
56
|
+
#-------------------------------------------------------------
|
57
|
+
|
58
|
+
#=============== GETTERS ==============================
|
59
|
+
|
60
|
+
[:width, :height].each do |m|
|
61
|
+
define_method "formatted_#{ m }" do
|
62
|
+
value = send("image_#{ m }")
|
63
|
+
pixels_to_emus(value, image_ppi)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
[:top, :bottom, :left, :right].each do |m|
|
68
|
+
define_method "formatted_#{ m }" do
|
69
|
+
value = send("image_#{ m }")
|
70
|
+
pixels_to_emus(value, 72)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def relationship_target
|
75
|
+
image_url || image_data
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
#=============== SETTERS ==============================
|
80
|
+
|
81
|
+
# integers
|
82
|
+
[:ppi, :width, :height, :top, :bottom, :left, :right].each do |m|
|
83
|
+
define_method "#{ m }" do |value|
|
84
|
+
instance_variable_set("@image_#{ m }", value.to_i)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# strings
|
89
|
+
[:data, :url].each do |m|
|
90
|
+
define_method "#{ m }" do |value|
|
91
|
+
instance_variable_set("@image_#{ m }", value.to_s)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# symbols
|
96
|
+
[:align].each do |m|
|
97
|
+
define_method "#{ m }" do |value|
|
98
|
+
instance_variable_set("@image_#{ m }", value.to_s.to_sym)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
#=============== VALIDATION ==============================
|
104
|
+
|
105
|
+
def valid?
|
106
|
+
dims = [:ppi, :width, :height, :top, :bottom, :left, :right].map { |m| send("image_#{ m }") }
|
107
|
+
dims.all? { |d| d > 0 }
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
#-------------------------------------------------------------
|
113
|
+
# Private Methods
|
114
|
+
#-------------------------------------------------------------
|
115
|
+
private
|
116
|
+
|
117
|
+
def option_keys
|
118
|
+
[:url, :width, :height, :align, :top, :bottom, :left, :right]
|
119
|
+
end
|
120
|
+
|
121
|
+
def pixels_to_emus(value, ppi)
|
122
|
+
pixels = value.to_i
|
123
|
+
inches = pixels / ppi.to_f
|
124
|
+
emus_per_inch = 914400
|
125
|
+
|
126
|
+
emus = (inches * emus_per_inch).to_i
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
# line break data.
|
10
|
+
#
|
11
|
+
class LineBreakModel < BaseModel; end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'caracal/core/models/text_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
|
+
# link data.
|
10
|
+
#
|
11
|
+
class LinkModel < TextModel
|
12
|
+
|
13
|
+
#--------------------------------------------------
|
14
|
+
# Configuration
|
15
|
+
#--------------------------------------------------
|
16
|
+
|
17
|
+
# constants
|
18
|
+
const_set(:DEFAULT_LINK_COLOR, '1155cc')
|
19
|
+
const_set(:DEFAULT_LINK_UNDERLINE, true)
|
20
|
+
|
21
|
+
# readers (create aliases for superclass methods to conform
|
22
|
+
# to expected naming convention.)
|
23
|
+
attr_reader :link_href
|
24
|
+
attr_reader :link_internal
|
25
|
+
alias_method :link_content, :text_content
|
26
|
+
alias_method :link_font, :text_font
|
27
|
+
alias_method :link_color, :text_color
|
28
|
+
alias_method :link_size, :text_size
|
29
|
+
alias_method :link_bold, :text_bold
|
30
|
+
alias_method :link_italic, :text_italic
|
31
|
+
alias_method :link_underline, :text_underline
|
32
|
+
alias_method :link_bgcolor, :text_bgcolor
|
33
|
+
alias_method :link_highlight_color, :text_highlight_color
|
34
|
+
alias_method :link_vertical_align, :text_vertical_align
|
35
|
+
|
36
|
+
# initialization
|
37
|
+
def initialize(options={}, &block)
|
38
|
+
@text_color = DEFAULT_LINK_COLOR
|
39
|
+
@text_underline = DEFAULT_LINK_UNDERLINE
|
40
|
+
|
41
|
+
super options, &block
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
#--------------------------------------------------
|
46
|
+
# Public Instance Methods
|
47
|
+
#--------------------------------------------------
|
48
|
+
|
49
|
+
#========== SETTERS ===============================
|
50
|
+
|
51
|
+
# booleans
|
52
|
+
[:internal].each do |m|
|
53
|
+
define_method "#{ m }" do |value|
|
54
|
+
instance_variable_set("@link_#{ m }", !!value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# strings
|
59
|
+
[:href].each do |m|
|
60
|
+
define_method "#{ m }" do |value|
|
61
|
+
instance_variable_set("@link_#{ m }", value.to_s)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
#========== STATE HELPERS =========================
|
67
|
+
|
68
|
+
def external?
|
69
|
+
!link_internal
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
#========== VALIDATION ============================
|
74
|
+
|
75
|
+
def valid?
|
76
|
+
a = [:content, :href]
|
77
|
+
a.map { |m| send("link_#{ m }") }.compact.size == a.size
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
#--------------------------------------------------
|
82
|
+
# Private Instance Methods
|
83
|
+
#--------------------------------------------------
|
84
|
+
private
|
85
|
+
|
86
|
+
def option_keys
|
87
|
+
(super + [:internal, :href]).flatten
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|