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.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +22 -0
  3. data/.github/workflows/publish_gem.yml +40 -0
  4. data/.gitignore +25 -0
  5. data/.travis.yml +20 -0
  6. data/CHANGELOG.md +141 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +842 -0
  10. data/Rakefile +7 -0
  11. data/caracal.gemspec +28 -0
  12. data/lib/caracal/core/bookmarks.rb +52 -0
  13. data/lib/caracal/core/custom_properties.rb +49 -0
  14. data/lib/caracal/core/file_name.rb +43 -0
  15. data/lib/caracal/core/fonts.rb +75 -0
  16. data/lib/caracal/core/iframes.rb +42 -0
  17. data/lib/caracal/core/ignorables.rb +47 -0
  18. data/lib/caracal/core/images.rb +37 -0
  19. data/lib/caracal/core/list_styles.rb +93 -0
  20. data/lib/caracal/core/lists.rb +57 -0
  21. data/lib/caracal/core/models/base_model.rb +51 -0
  22. data/lib/caracal/core/models/bookmark_model.rb +86 -0
  23. data/lib/caracal/core/models/border_model.rb +120 -0
  24. data/lib/caracal/core/models/custom_property_model.rb +60 -0
  25. data/lib/caracal/core/models/font_model.rb +64 -0
  26. data/lib/caracal/core/models/iframe_model.rb +148 -0
  27. data/lib/caracal/core/models/image_model.rb +133 -0
  28. data/lib/caracal/core/models/line_break_model.rb +15 -0
  29. data/lib/caracal/core/models/link_model.rb +94 -0
  30. data/lib/caracal/core/models/list_item_model.rb +108 -0
  31. data/lib/caracal/core/models/list_model.rb +132 -0
  32. data/lib/caracal/core/models/list_style_model.rb +118 -0
  33. data/lib/caracal/core/models/margin_model.rb +76 -0
  34. data/lib/caracal/core/models/namespace_model.rb +65 -0
  35. data/lib/caracal/core/models/page_break_model.rb +61 -0
  36. data/lib/caracal/core/models/page_number_model.rb +95 -0
  37. data/lib/caracal/core/models/page_size_model.rb +79 -0
  38. data/lib/caracal/core/models/paragraph_model.rb +186 -0
  39. data/lib/caracal/core/models/relationship_model.rb +114 -0
  40. data/lib/caracal/core/models/rule_model.rb +27 -0
  41. data/lib/caracal/core/models/style_model.rb +165 -0
  42. data/lib/caracal/core/models/table_cell_model.rb +176 -0
  43. data/lib/caracal/core/models/table_model.rb +206 -0
  44. data/lib/caracal/core/models/text_model.rb +118 -0
  45. data/lib/caracal/core/namespaces.rb +89 -0
  46. data/lib/caracal/core/page_breaks.rb +29 -0
  47. data/lib/caracal/core/page_numbers.rb +58 -0
  48. data/lib/caracal/core/page_settings.rb +74 -0
  49. data/lib/caracal/core/relationships.rb +90 -0
  50. data/lib/caracal/core/rules.rb +35 -0
  51. data/lib/caracal/core/styles.rb +86 -0
  52. data/lib/caracal/core/tables.rb +42 -0
  53. data/lib/caracal/core/text.rb +75 -0
  54. data/lib/caracal/document.rb +272 -0
  55. data/lib/caracal/errors.rb +23 -0
  56. data/lib/caracal/renderers/app_renderer.rb +41 -0
  57. data/lib/caracal/renderers/content_types_renderer.rb +54 -0
  58. data/lib/caracal/renderers/core_renderer.rb +44 -0
  59. data/lib/caracal/renderers/custom_renderer.rb +64 -0
  60. data/lib/caracal/renderers/document_renderer.rb +427 -0
  61. data/lib/caracal/renderers/fonts_renderer.rb +56 -0
  62. data/lib/caracal/renderers/footer_renderer.rb +90 -0
  63. data/lib/caracal/renderers/numbering_renderer.rb +88 -0
  64. data/lib/caracal/renderers/package_relationships_renderer.rb +51 -0
  65. data/lib/caracal/renderers/relationships_renderer.rb +48 -0
  66. data/lib/caracal/renderers/settings_renderer.rb +58 -0
  67. data/lib/caracal/renderers/styles_renderer.rb +181 -0
  68. data/lib/caracal/renderers/xml_renderer.rb +83 -0
  69. data/lib/caracal/utilities.rb +23 -0
  70. data/lib/caracal/version.rb +3 -0
  71. data/lib/caracal.rb +40 -0
  72. data/lib/tilt/caracal.rb +21 -0
  73. data/spec/lib/caracal/core/bookmarks_spec.rb +35 -0
  74. data/spec/lib/caracal/core/file_name_spec.rb +54 -0
  75. data/spec/lib/caracal/core/fonts_spec.rb +119 -0
  76. data/spec/lib/caracal/core/iframes_spec.rb +29 -0
  77. data/spec/lib/caracal/core/ignorables_spec.rb +79 -0
  78. data/spec/lib/caracal/core/images_spec.rb +25 -0
  79. data/spec/lib/caracal/core/list_styles_spec.rb +121 -0
  80. data/spec/lib/caracal/core/lists_spec.rb +43 -0
  81. data/spec/lib/caracal/core/models/base_model_spec.rb +38 -0
  82. data/spec/lib/caracal/core/models/bookmark_model_spec.rb +135 -0
  83. data/spec/lib/caracal/core/models/border_model_spec.rb +159 -0
  84. data/spec/lib/caracal/core/models/font_model_spec.rb +92 -0
  85. data/spec/lib/caracal/core/models/iframe_model_spec.rb +83 -0
  86. data/spec/lib/caracal/core/models/image_model_spec.rb +225 -0
  87. data/spec/lib/caracal/core/models/line_break_model_spec.rb +21 -0
  88. data/spec/lib/caracal/core/models/link_model_spec.rb +179 -0
  89. data/spec/lib/caracal/core/models/list_item_model_spec.rb +197 -0
  90. data/spec/lib/caracal/core/models/list_model_spec.rb +178 -0
  91. data/spec/lib/caracal/core/models/list_style_model_spec.rb +198 -0
  92. data/spec/lib/caracal/core/models/margin_model_spec.rb +111 -0
  93. data/spec/lib/caracal/core/models/namespace_model_spec.rb +107 -0
  94. data/spec/lib/caracal/core/models/page_break_model_spec.rb +21 -0
  95. data/spec/lib/caracal/core/models/page_number_model_spec.rb +136 -0
  96. data/spec/lib/caracal/core/models/page_size_model_spec.rb +101 -0
  97. data/spec/lib/caracal/core/models/paragraph_model_spec.rb +196 -0
  98. data/spec/lib/caracal/core/models/relationship_model_spec.rb +193 -0
  99. data/spec/lib/caracal/core/models/rule_model_spec.rb +108 -0
  100. data/spec/lib/caracal/core/models/style_model_spec.rb +225 -0
  101. data/spec/lib/caracal/core/models/table_cell_model_spec.rb +230 -0
  102. data/spec/lib/caracal/core/models/table_model_spec.rb +222 -0
  103. data/spec/lib/caracal/core/models/text_model_spec.rb +154 -0
  104. data/spec/lib/caracal/core/namespaces_spec.rb +116 -0
  105. data/spec/lib/caracal/core/page_breaks_spec.rb +25 -0
  106. data/spec/lib/caracal/core/page_numbers_spec.rb +89 -0
  107. data/spec/lib/caracal/core/page_settings_spec.rb +151 -0
  108. data/spec/lib/caracal/core/relationships_spec.rb +119 -0
  109. data/spec/lib/caracal/core/rules_spec.rb +25 -0
  110. data/spec/lib/caracal/core/styles_spec.rb +129 -0
  111. data/spec/lib/caracal/core/tables_spec.rb +25 -0
  112. data/spec/lib/caracal/core/text_spec.rb +52 -0
  113. data/spec/lib/caracal/errors_spec.rb +10 -0
  114. data/spec/spec_helper.rb +8 -0
  115. data/spec/support/_fixtures/snippet.docx +0 -0
  116. metadata +292 -0
@@ -0,0 +1,79 @@
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 size
9
+ # method.
10
+ #
11
+ class PageSizeModel < BaseModel
12
+
13
+ #-------------------------------------------------------------
14
+ # Configuration
15
+ #-------------------------------------------------------------
16
+
17
+ # constants
18
+ const_set(:DEFAULT_PAGE_WIDTH, 12240) # 8.5in in twips
19
+ const_set(:DEFAULT_PAGE_HEIGHT, 15840) # 11.0in in twips
20
+ const_set(:DEFAULT_PAGE_ORIENTATION, 'portrait')
21
+
22
+ # accessors
23
+ attr_reader :page_width
24
+ attr_reader :page_height
25
+ attr_reader :page_orientation
26
+
27
+ # initialization
28
+ def initialize(options={}, &block)
29
+ @page_width = DEFAULT_PAGE_WIDTH
30
+ @page_height = DEFAULT_PAGE_HEIGHT
31
+ @page_orientation = DEFAULT_PAGE_ORIENTATION
32
+
33
+ super options, &block
34
+ end
35
+
36
+
37
+ #-------------------------------------------------------------
38
+ # Public Methods
39
+ #-------------------------------------------------------------
40
+
41
+ #=============== SETTERS ==============================
42
+
43
+ def height(value)
44
+ @page_height = value.to_i
45
+ end
46
+
47
+ def orientation(value)
48
+ allowed = ['landscape','portrait']
49
+ given = value.to_s.downcase
50
+ @page_orientation = allowed.include?(given) ? given : 'portrait'
51
+ end
52
+
53
+ def width(value)
54
+ @page_width = value.to_i
55
+ end
56
+
57
+
58
+ #=============== VALIDATION ==============================
59
+
60
+ def valid?
61
+ dims = [page_width, page_height]
62
+ dims.all? { |d| d > 0 }
63
+ end
64
+
65
+
66
+ #-------------------------------------------------------------
67
+ # Private Instance Methods
68
+ #-------------------------------------------------------------
69
+ private
70
+
71
+ def option_keys
72
+ [:width, :height, :orientation]
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,186 @@
1
+ require 'caracal/core/models/base_model'
2
+ require 'caracal/core/models/bookmark_model'
3
+ require 'caracal/core/models/link_model'
4
+ require 'caracal/core/models/text_model'
5
+ require 'caracal/errors'
6
+
7
+
8
+ module Caracal
9
+ module Core
10
+ module Models
11
+
12
+ # This class encapsulates the logic needed to store and manipulate
13
+ # paragraph data.
14
+ #
15
+ class ParagraphModel < BaseModel
16
+
17
+ #--------------------------------------------------
18
+ # Configuration
19
+ #--------------------------------------------------
20
+
21
+ # readers
22
+ attr_reader :paragraph_style
23
+ attr_reader :paragraph_align
24
+ attr_reader :paragraph_color
25
+ attr_reader :paragraph_size
26
+ attr_reader :paragraph_bold
27
+ attr_reader :paragraph_italic
28
+ attr_reader :paragraph_underline
29
+ attr_reader :paragraph_bgcolor
30
+
31
+ # initialization
32
+ def initialize(options={}, &block)
33
+ content = options.delete(:content) { "" }
34
+ text content, options.dup, &block
35
+ super options, &block
36
+ end
37
+
38
+
39
+ #--------------------------------------------------
40
+ # Public Instance Methods
41
+ #--------------------------------------------------
42
+
43
+ #========== GETTERS ===============================
44
+
45
+ # .runs
46
+ def runs
47
+ @runs ||= []
48
+ end
49
+
50
+ # .run_attributes
51
+ def run_attributes
52
+ {
53
+ color: paragraph_color,
54
+ size: paragraph_size,
55
+ bold: paragraph_bold,
56
+ italic: paragraph_italic,
57
+ underline: paragraph_underline,
58
+ bgcolor: paragraph_bgcolor
59
+ }
60
+ end
61
+
62
+
63
+ #========== SETTERS ===============================
64
+
65
+ # booleans
66
+ [:bold, :italic, :underline].each do |m|
67
+ define_method "#{ m }" do |value|
68
+ instance_variable_set("@paragraph_#{ m }", !!value)
69
+ end
70
+ end
71
+
72
+ # integers
73
+ [:size].each do |m|
74
+ define_method "#{ m }" do |value|
75
+ instance_variable_set("@paragraph_#{ m }", value.to_i)
76
+ end
77
+ end
78
+
79
+ # strings
80
+ [:bgcolor, :color, :style].each do |m|
81
+ define_method "#{ m }" do |value|
82
+ instance_variable_set("@paragraph_#{ m }", value.to_s)
83
+ end
84
+ end
85
+
86
+ # symbols
87
+ [:align].each do |m|
88
+ define_method "#{ m }" do |value|
89
+ instance_variable_set("@paragraph_#{ m }", value.to_s.to_sym)
90
+ end
91
+ end
92
+
93
+
94
+ #========== SUB-METHODS ===========================
95
+
96
+ # .bookmarks
97
+ def bookmark_start(*args, &block)
98
+ options = Caracal::Utilities.extract_options!(args)
99
+ options.merge!({ start: true})
100
+
101
+ model = Caracal::Core::Models::BookmarkModel.new(options, &block)
102
+ if model.valid?
103
+ runs << model
104
+ else
105
+ raise Caracal::Errors::InvalidModelError, 'Bookmark starting tags require an id and a name.'
106
+ end
107
+ model
108
+ end
109
+ def bookmark_end(*args, &block)
110
+ options = Caracal::Utilities.extract_options!(args)
111
+ options.merge!({ start: false})
112
+
113
+ model = Caracal::Core::Models::BookmarkModel.new(options, &block)
114
+ if model.valid?
115
+ runs << model
116
+ else
117
+ raise Caracal::Errors::InvalidModelError, 'Bookmark ending tags require an id.'
118
+ end
119
+ model
120
+ end
121
+
122
+ # .br
123
+ def br
124
+ model = Caracal::Core::Models::LineBreakModel.new()
125
+ runs << model
126
+ model
127
+ end
128
+
129
+ # .link
130
+ def link(*args, &block)
131
+ options = Caracal::Utilities.extract_options!(args)
132
+ options.merge!({ content: args[0] }) if args[0]
133
+ options.merge!({ href: args[1] }) if args[1]
134
+
135
+ model = Caracal::Core::Models::LinkModel.new(options, &block)
136
+ if model.valid?
137
+ runs << model
138
+ else
139
+ raise Caracal::Errors::InvalidModelError, ':link method must receive strings for the display text and the external href.'
140
+ end
141
+ model
142
+ end
143
+
144
+ # .page
145
+ def page
146
+ model = Caracal::Core::Models::PageBreakModel.new({ wrap: false })
147
+ runs << model
148
+ model
149
+ end
150
+
151
+ # .text
152
+ def text(*args, &block)
153
+ options = Caracal::Utilities.extract_options!(args)
154
+ options.merge!({ content: args.first }) if args.first
155
+
156
+ model = Caracal::Core::Models::TextModel.new(options, &block)
157
+ if model.valid?
158
+ runs << model
159
+ else
160
+ raise Caracal::Errors::InvalidModelError, ':text method must receive a string for the display text.'
161
+ end
162
+ model
163
+ end
164
+
165
+
166
+ #========== VALIDATION ============================
167
+
168
+ def valid?
169
+ runs.size > 0
170
+ end
171
+
172
+
173
+ #--------------------------------------------------
174
+ # Private Instance Methods
175
+ #--------------------------------------------------
176
+ private
177
+
178
+ def option_keys
179
+ [:content, :style, :align, :color, :size, :bold, :italic, :underline, :bgcolor]
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,114 @@
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
+ # relationship data.
10
+ #
11
+ class RelationshipModel < BaseModel
12
+
13
+ #-------------------------------------------------------------
14
+ # Configuration
15
+ #-------------------------------------------------------------
16
+
17
+ # constants
18
+ TYPE_MAP = {
19
+ font: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable',
20
+ footer: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer',
21
+ image: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
22
+ link: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
23
+ numbering: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering',
24
+ setting: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings',
25
+ style: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles'
26
+ }
27
+
28
+ # accessors
29
+ attr_reader :relationship_id
30
+ attr_reader :relationship_key
31
+ attr_reader :relationship_type
32
+ attr_reader :relationship_target
33
+ attr_reader :relationship_data
34
+
35
+
36
+
37
+ #-------------------------------------------------------------
38
+ # Public Instance Methods
39
+ #-------------------------------------------------------------
40
+
41
+ #=================== GETTERS =============================
42
+
43
+ def formatted_id
44
+ "rId#{ relationship_id }"
45
+ end
46
+
47
+ def formatted_target
48
+ if relationship_type == :image
49
+ ext = relationship_target.to_s.split('.').last
50
+ ext = ext.split('?').first
51
+ "media/image#{ relationship_id }.#{ ext }"
52
+ else
53
+ relationship_target
54
+ end
55
+ end
56
+
57
+ def formatted_type
58
+ TYPE_MAP.fetch(relationship_type)
59
+ end
60
+
61
+
62
+ #=================== SETTERS =============================
63
+
64
+ def id(value)
65
+ @relationship_id = value.to_i
66
+ end
67
+
68
+ def type(value)
69
+ @relationship_type = value.to_s.downcase.to_sym
70
+ end
71
+
72
+ def target(value)
73
+ @relationship_target = value.to_s
74
+ @relationship_key = value.to_s.downcase
75
+ end
76
+
77
+ def data(value)
78
+ @relationship_data = value.to_s
79
+ end
80
+
81
+
82
+ #=================== STATE ===============================
83
+
84
+ def matches?(str)
85
+ relationship_key.downcase == str.to_s.downcase
86
+ end
87
+
88
+ def target_mode?
89
+ relationship_type == :link
90
+ end
91
+
92
+
93
+ #=============== VALIDATION ===========================
94
+
95
+ def valid?
96
+ required = [:id, :target, :type]
97
+ required.all? { |m| !send("relationship_#{ m }").nil? }
98
+ end
99
+
100
+
101
+ #-------------------------------------------------------------
102
+ # Private Instance Methods
103
+ #-------------------------------------------------------------
104
+ private
105
+
106
+ def option_keys
107
+ [:id, :type, :target, :data]
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,27 @@
1
+ require 'caracal/core/models/border_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 RuleModel < BorderModel
12
+
13
+ #-------------------------------------------------------------
14
+ # Configuration
15
+ #-------------------------------------------------------------
16
+
17
+ # aliases
18
+ alias_method :rule_color, :border_color
19
+ alias_method :rule_size, :border_size
20
+ alias_method :rule_spacing, :border_spacing
21
+ alias_method :rule_line, :border_line
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,165 @@
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
+ # paragraph style data.
10
+ #
11
+ class StyleModel < BaseModel
12
+
13
+ #--------------------------------------------------
14
+ # Configuration
15
+ #--------------------------------------------------
16
+
17
+ # constants
18
+ const_set(:DEFAULT_STYLE_TYPE, 'paragraph')
19
+ const_set(:DEFAULT_STYLE_COLOR, '333333')
20
+ const_set(:DEFAULT_STYLE_SIZE, 20)
21
+ const_set(:DEFAULT_STYLE_BOLD, false)
22
+ const_set(:DEFAULT_STYLE_ITALIC, false)
23
+ const_set(:DEFAULT_STYLE_UNDERLINE, false)
24
+ const_set(:DEFAULT_STYLE_CAPS, false)
25
+ const_set(:DEFAULT_STYLE_ALIGN, :left)
26
+ const_set(:DEFAULT_STYLE_LINE, 360) # 0.25in in twips
27
+ const_set(:DEFAULT_STYLE_TOP, 0) # 0.0in in twips
28
+ const_set(:DEFAULT_STYLE_BOTTOM, 0) # 0.0in in twips
29
+ const_set(:DEFAULT_STYLE_BASE, 'Normal')
30
+ const_set(:DEFAULT_STYLE_NEXT, 'Normal')
31
+
32
+ # accessors
33
+ attr_reader :style_default
34
+ attr_reader :style_id
35
+ attr_reader :style_type
36
+ attr_reader :style_name
37
+ attr_reader :style_color
38
+ attr_reader :style_font
39
+ attr_reader :style_size
40
+ attr_reader :style_bold
41
+ attr_reader :style_italic
42
+ attr_reader :style_underline
43
+ attr_reader :style_caps
44
+ attr_reader :style_align
45
+ attr_reader :style_top
46
+ attr_reader :style_bottom
47
+ attr_reader :style_line
48
+ attr_reader :style_base
49
+ attr_reader :style_next
50
+ attr_reader :style_indent_left
51
+ attr_reader :style_indent_right
52
+ attr_reader :style_indent_first
53
+
54
+ # initialization
55
+ def initialize(options={}, &block)
56
+ @style_default = false
57
+ @style_type = DEFAULT_STYLE_TYPE
58
+ @style_base = DEFAULT_STYLE_BASE
59
+ @style_next = DEFAULT_STYLE_NEXT
60
+
61
+ super options, &block
62
+
63
+ if (style_id == DEFAULT_STYLE_BASE)
64
+ @style_default ||= true
65
+ @style_color ||= DEFAULT_STYLE_COLOR
66
+ @style_size ||= DEFAULT_STYLE_SIZE
67
+ @style_bold ||= DEFAULT_STYLE_BOLD
68
+ @style_italic ||= DEFAULT_STYLE_ITALIC
69
+ @style_underline ||= DEFAULT_STYLE_UNDERLINE
70
+ @style_caps ||= DEFAULT_STYLE_CAPS
71
+ @style_align ||= DEFAULT_STYLE_ALIGN
72
+ @style_top ||= DEFAULT_STYLE_TOP
73
+ @style_bottom ||= DEFAULT_STYLE_BOTTOM
74
+ @style_line ||= DEFAULT_STYLE_LINE
75
+ end
76
+ end
77
+
78
+
79
+ #--------------------------------------------------
80
+ # Public Methods
81
+ #--------------------------------------------------
82
+
83
+ #========== SETTERS ===============================
84
+
85
+ # booleans
86
+ [:bold, :italic, :underline, :caps].each do |m|
87
+ define_method "#{ m }" do |value|
88
+ instance_variable_set("@style_#{ m }", !!value)
89
+ end
90
+ end
91
+
92
+ # integers
93
+ [:bottom, :size, :line, :top, :indent_left, :indent_right, :indent_first].each do |m|
94
+ define_method "#{ m }" do |value|
95
+ instance_variable_set("@style_#{ m }", value.to_i)
96
+ end
97
+ end
98
+
99
+ # strings
100
+ [:id, :type, :name, :color, :font].each do |m|
101
+ define_method "#{ m }" do |value|
102
+ instance_variable_set("@style_#{ m }", value.to_s)
103
+ end
104
+ end
105
+
106
+ # symbols
107
+ [:align].each do |m|
108
+ define_method "#{ m }" do |value|
109
+ instance_variable_set("@style_#{ m }", value.to_s.to_sym)
110
+ end
111
+ end
112
+
113
+ # custom
114
+ def type(value)
115
+ allowed = ['character', 'paragraph']
116
+ given = value.to_s.downcase.strip
117
+ @style_type = allowed.include?(given) ? given : DEFAULT_STYLE_TYPE
118
+ end
119
+
120
+
121
+ #========== STATE =================================
122
+
123
+ def matches?(str)
124
+ style_id.downcase == str.to_s.downcase
125
+ end
126
+
127
+
128
+ #========== VALIDATION ============================
129
+
130
+ def valid?
131
+ a = [:id, :name, :type]
132
+ a.map { |m| send("style_#{ m }") }.compact.size == a.size
133
+ end
134
+
135
+
136
+ #--------------------------------------------------
137
+ # Private Methods
138
+ #--------------------------------------------------
139
+ private
140
+
141
+ def option_keys
142
+ [ :type,
143
+ :bold,
144
+ :italic,
145
+ :underline,
146
+ :caps,
147
+ :top,
148
+ :bottom,
149
+ :size,
150
+ :line,
151
+ :id,
152
+ :name,
153
+ :color,
154
+ :font,
155
+ :align,
156
+ :indent_left,
157
+ :indent_right,
158
+ :indent_first ]
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+ end
165
+ end