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,176 @@
1
+ require 'caracal/core/models/base_model'
2
+ require 'caracal/core/models/margin_model'
3
+ require 'caracal/core/models/paragraph_model'
4
+
5
+
6
+ module Caracal
7
+ module Core
8
+ module Models
9
+
10
+ # This class handles block options passed to tables via their data
11
+ # collections.
12
+ #
13
+ class TableCellModel < BaseModel
14
+
15
+ #-------------------------------------------------------------
16
+ # Configuration
17
+ #-------------------------------------------------------------
18
+
19
+ # constants
20
+ const_set(:DEFAULT_CELL_BACKGROUND, 'ffffff')
21
+ const_set(:DEFAULT_CELL_MARGINS, Caracal::Core::Models::MarginModel.new({ top: 100, bottom: 100, left: 100, right: 100 }))
22
+ const_set(:DEFAULT_CELL_VERTICAL_ALIGN, :top)
23
+
24
+ # accessors
25
+ attr_reader :cell_background
26
+ attr_reader :cell_width
27
+ attr_reader :cell_margins
28
+ attr_reader :cell_vertical_align
29
+ attr_reader :cell_rowspan
30
+ attr_reader :cell_colspan
31
+
32
+ # initialization
33
+ def initialize(options={}, &block)
34
+ @cell_background = DEFAULT_CELL_BACKGROUND
35
+ @cell_margins = DEFAULT_CELL_MARGINS
36
+ @cell_vertical_align = DEFAULT_CELL_VERTICAL_ALIGN
37
+
38
+ if content = options.delete(:content)
39
+ p content, options.dup, &block
40
+ end
41
+
42
+ super options, &block
43
+
44
+ p_klass = Caracal::Core::Models::ParagraphModel # the final tag in a table cell
45
+ unless contents.last.is_a? p_klass # *must* be a paragraph for OOXML
46
+ contents << p_klass.new(content: '') # to not throw an error.
47
+ end
48
+ end
49
+
50
+
51
+ #-------------------------------------------------------------
52
+ # Public Methods
53
+ #-------------------------------------------------------------
54
+
55
+ #=============== DATA ACCESSORS =======================
56
+
57
+ def contents
58
+ @contents ||= []
59
+ end
60
+
61
+
62
+ #=============== STYLES ===============================
63
+
64
+ # This method allows styles to be applied to this cell
65
+ # from the table level. It attempts to add the style
66
+ # first to the instance, and then to any sub-models that
67
+ # respond to the method.
68
+ #
69
+ # In all cases, invalid options will simply be ignored.
70
+ #
71
+ def apply_styles(opts={})
72
+ # make dup of options so we don't
73
+ # harm args sent to sibling cells
74
+ options = opts.dup
75
+
76
+ # first, try apply to self
77
+ options.each do |(k,v)|
78
+ send(k, v) if respond_to?(k)
79
+ end
80
+
81
+ # prevent top-level attrs from trickling down
82
+ options.delete_if { |(k,v)| option_keys.include?(k) }
83
+
84
+ # then, try apply to contents
85
+ contents.each do |model|
86
+ options.each do |k,v|
87
+ model.send(k, v) if model.respond_to?(k)
88
+ end
89
+
90
+ # finally, apply to runs. options do trickle down
91
+ # because paragraph-level styles don't seem to
92
+ # affect runs within tables. weirdsies.
93
+ if model.respond_to?(:runs)
94
+ model.runs.each do |run|
95
+ options.each do |k,v|
96
+ run.send(k, v) if run.respond_to?(k)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ def calculate_width(default_width)
104
+ width(default_width) unless cell_width.to_i > 0
105
+
106
+ container_width = cell_width - cell_margin_left - cell_margin_right
107
+
108
+ contents.each do |model|
109
+ if model.respond_to?(:calculate_width)
110
+ model.calculate_width(container_width) # will always be a TableModel
111
+ end
112
+ end
113
+ end
114
+
115
+
116
+ #=============== GETTERS ==============================
117
+
118
+ # margin attrs
119
+ [:top, :bottom, :left, :right].each do |m|
120
+ define_method "cell_margin_#{ m }" do
121
+ v = cell_margins ? cell_margins.send("margin_#{ m }") : 0
122
+ end
123
+ end
124
+
125
+
126
+ #=============== SETTERS ==============================
127
+
128
+ # integers
129
+ [:width, :colspan, :rowspan].each do |m|
130
+ define_method "#{ m }" do |value|
131
+ instance_variable_set("@cell_#{ m }", value.to_i)
132
+ end
133
+ end
134
+
135
+ # models
136
+ [:margins].each do |m|
137
+ define_method "#{ m }" do |options = {}, &block|
138
+ instance_variable_set("@cell_#{ m }", Caracal::Core::Models::MarginModel.new(options, &block))
139
+ end
140
+ end
141
+
142
+ # strings
143
+ [:background].each do |m|
144
+ define_method "#{ m }" do |value|
145
+ instance_variable_set("@cell_#{ m }", value.to_s)
146
+ end
147
+ end
148
+
149
+ #symbols
150
+ [:vertical_align].each do |m|
151
+ define_method "#{ m }" do |value|
152
+ instance_variable_set("@cell_#{ m }", value.to_s.to_sym)
153
+ end
154
+ end
155
+
156
+ #=============== VALIDATION ===========================
157
+
158
+ def valid?
159
+ contents.size > 0
160
+ end
161
+
162
+
163
+ #-------------------------------------------------------------
164
+ # Private Instance Methods
165
+ #-------------------------------------------------------------
166
+ private
167
+
168
+ def option_keys
169
+ [:background, :margins, :width, :vertical_align, :rowspan, :colspan]
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,206 @@
1
+ require 'caracal/core/models/base_model'
2
+ require 'caracal/core/models/border_model'
3
+ require 'caracal/core/models/table_cell_model'
4
+
5
+
6
+ module Caracal
7
+ module Core
8
+ module Models
9
+
10
+ # This class handles block options passed to the table
11
+ # method.
12
+ #
13
+ class TableModel < BaseModel
14
+
15
+ #-------------------------------------------------------------
16
+ # Configuration
17
+ #-------------------------------------------------------------
18
+
19
+ # constants
20
+ const_set(:DEFAULT_TABLE_ALIGN, :center) # weirdly, works better w/ full width
21
+ const_set(:DEFAULT_TABLE_BORDER_COLOR, 'auto')
22
+ const_set(:DEFAULT_TABLE_BORDER_LINE, :single)
23
+ const_set(:DEFAULT_TABLE_BORDER_SIZE, 0) # units in 1/8 points
24
+ const_set(:DEFAULT_TABLE_BORDER_SPACING, 0)
25
+
26
+ # accessors
27
+ attr_reader :table_align
28
+ attr_reader :table_width
29
+ attr_reader :table_border_color
30
+ attr_reader :table_border_line
31
+ attr_reader :table_border_size
32
+ attr_reader :table_border_spacing
33
+ attr_reader :table_border_top # returns border model
34
+ attr_reader :table_border_bottom # returns border model
35
+ attr_reader :table_border_left # returns border model
36
+ attr_reader :table_border_right # returns border model
37
+ attr_reader :table_border_horizontal # returns border model
38
+ attr_reader :table_border_vertical # returns border model
39
+
40
+ # initialization
41
+ def initialize(options={}, &block)
42
+ @table_align = DEFAULT_TABLE_ALIGN
43
+ @table_border_color = DEFAULT_TABLE_BORDER_COLOR
44
+ @table_border_line = DEFAULT_TABLE_BORDER_LINE
45
+ @table_border_size = DEFAULT_TABLE_BORDER_SIZE
46
+ @table_border_spacing = DEFAULT_TABLE_BORDER_SPACING
47
+
48
+ super options, &block
49
+ end
50
+
51
+
52
+ #-------------------------------------------------------------
53
+ # Public Methods
54
+ #-------------------------------------------------------------
55
+
56
+ #=============== DATA ACCESSORS =======================
57
+
58
+ def cells
59
+ rows.flatten
60
+ end
61
+
62
+ def cols
63
+ rows.reduce([]) do |array, row|
64
+ row.each_with_index do |cell, index|
65
+ array[index] = [] if array[index].nil?
66
+ array[index] << cell
67
+ end
68
+ array
69
+ end
70
+ end
71
+
72
+ def rows
73
+ @table_data || [[]]
74
+ end
75
+
76
+
77
+ #=============== STYLES ===============================
78
+
79
+ # This method sets explicit widths on all wrapped cells
80
+ # that do not already have widths asided.
81
+ #
82
+ def calculate_width(container_width)
83
+ width(container_width) unless table_width.to_i > 0
84
+
85
+ cells.each { |c| c.calculate_width(default_cell_width) }
86
+ end
87
+
88
+ # This method allows tables to be styled several cells
89
+ # at a time.
90
+ #
91
+ # For example, this would style a header row.
92
+ #
93
+ # docx.table data do |t|
94
+ # t.cell_style t.rows[0], background: '3366cc', color: 'ffffff', bold: true
95
+ # end
96
+ #
97
+ def cell_style(models, options={})
98
+ [models].flatten.compact.each do |m|
99
+ m.apply_styles(options)
100
+ end
101
+ end
102
+
103
+
104
+ #=============== GETTERS ==============================
105
+
106
+ # border attrs
107
+ [:top, :bottom, :left, :right, :horizontal, :vertical].each do |m|
108
+ [:color, :line, :size, :spacing].each do |attr|
109
+ define_method "table_border_#{ m }_#{ attr }" do
110
+ model = send("table_border_#{ m }")
111
+ value = (model) ? model.send("border_#{ attr }") : send("table_border_#{ attr }")
112
+ end
113
+ end
114
+ define_method "table_border_#{ m }_total_size" do
115
+ model = send("table_border_#{ m }")
116
+ value = (model) ? model.total_size : table_border_size + (2 * table_border_spacing)
117
+ end
118
+ end
119
+
120
+
121
+ #=============== SETTERS ==============================
122
+
123
+ # integers
124
+ [:border_size, :border_spacing, :width].each do |m|
125
+ define_method "#{ m }" do |value|
126
+ instance_variable_set("@table_#{ m }", value.to_i)
127
+ end
128
+ end
129
+
130
+ # models
131
+ [:top, :bottom, :left, :right, :horizontal, :vertical].each do |m|
132
+ define_method "border_#{ m }" do |options = {}, &block|
133
+ options.merge!({ type: m })
134
+ instance_variable_set("@table_border_#{ m }", Caracal::Core::Models::BorderModel.new(options, &block))
135
+ end
136
+ end
137
+
138
+ # strings
139
+ [:border_color].each do |m|
140
+ define_method "#{ m }" do |value|
141
+ instance_variable_set("@table_#{ m }", value.to_s)
142
+ end
143
+ end
144
+
145
+ # symbols
146
+ [:border_line, :align].each do |m|
147
+ define_method "#{ m }" do |value|
148
+ instance_variable_set("@table_#{ m }", value.to_s.to_sym)
149
+ end
150
+ end
151
+
152
+ # .data
153
+ def data(value)
154
+ begin
155
+ @table_data = value.map do |data_row|
156
+ data_row.map do |data_cell|
157
+ case data_cell
158
+ when Caracal::Core::Models::TableCellModel
159
+ data_cell
160
+ when Hash
161
+ Caracal::Core::Models::TableCellModel.new(data_cell)
162
+ when Proc
163
+ Caracal::Core::Models::TableCellModel.new(&data_cell)
164
+ else
165
+ Caracal::Core::Models::TableCellModel.new({ content: data_cell.to_s })
166
+ end
167
+ end
168
+ end
169
+ rescue
170
+ raise Caracal::Errors::InvalidTableDataError, 'Table data must be a two-dimensional array.'
171
+ end
172
+ end
173
+
174
+
175
+ #=============== VALIDATION ==============================
176
+
177
+ def valid?
178
+ cells.first.is_a?(Caracal::Core::Models::TableCellModel)
179
+ end
180
+
181
+
182
+ #-------------------------------------------------------------
183
+ # Private Instance Methods
184
+ #-------------------------------------------------------------
185
+ private
186
+
187
+ def default_cell_width
188
+ cell_widths = rows.first.map { |c| c.cell_width.to_i }
189
+ remaining_width = table_width - cell_widths.reduce(&:+).to_i
190
+ remaining_cols = cols.size - cell_widths.reject { |w| w == 0 }.size
191
+ default_width = (remaining_cols == 0) ? 0 : (remaining_width / remaining_cols)
192
+ end
193
+
194
+ def option_keys
195
+ k = []
196
+ k << [:data, :align, :width]
197
+ k << [:border_color, :border_line, :border_size, :border_spacing]
198
+ k << [:border_bottom, :border_left, :border_right, :border_top, :border_horizontal, :border_vertical]
199
+ k.flatten
200
+ end
201
+
202
+ end
203
+
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,118 @@
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
+ # text data.
10
+ #
11
+ class TextModel < BaseModel
12
+
13
+ #--------------------------------------------------
14
+ # Configuration
15
+ #--------------------------------------------------
16
+
17
+ # accessors
18
+ attr_reader :text_content
19
+ attr_reader :text_style
20
+ attr_reader :text_font
21
+ attr_reader :text_color
22
+ attr_reader :text_size
23
+ attr_reader :text_bold
24
+ attr_reader :text_italic
25
+ attr_reader :text_underline
26
+ attr_reader :text_bgcolor
27
+ attr_reader :text_highlight_color
28
+ attr_reader :text_vertical_align
29
+
30
+
31
+
32
+ #--------------------------------------------------
33
+ # Public Methods
34
+ #--------------------------------------------------
35
+
36
+ #========== GETTERS ===============================
37
+
38
+ # .run_attributes
39
+ def run_attributes
40
+ {
41
+ style: text_style,
42
+ font: text_font,
43
+ color: text_color,
44
+ size: text_size,
45
+ bold: text_bold,
46
+ italic: text_italic,
47
+ underline: text_underline,
48
+ bgcolor: text_bgcolor,
49
+ highlight_color: text_highlight_color,
50
+ vertical_align: text_vertical_align
51
+ }
52
+ end
53
+
54
+
55
+ #========== SETTERS ===============================
56
+
57
+ # booleans
58
+ [:bold, :italic, :underline].each do |m|
59
+ define_method "#{ m }" do |value|
60
+ instance_variable_set("@text_#{ m }", !!value)
61
+ end
62
+ end
63
+
64
+ # integers
65
+ [:size].each do |m|
66
+ define_method "#{ m }" do |value|
67
+ instance_variable_set("@text_#{ m }", value.to_i)
68
+ end
69
+ end
70
+
71
+ # strings
72
+ [:bgcolor, :color, :content, :font, :highlight_color, :style].each do |m|
73
+ define_method "#{ m }" do |value|
74
+ instance_variable_set("@text_#{ m }", value.to_s)
75
+ end
76
+ end
77
+
78
+ # symbols
79
+ [:vertical_align].each do |m|
80
+ define_method "#{ m }" do |value|
81
+ instance_variable_set("@text_#{ m }", value.to_s.to_sym)
82
+ end
83
+ end
84
+
85
+
86
+ #========== VALIDATION ============================
87
+
88
+ def valid?
89
+ a = [:content]
90
+ a.map { |m| send("text_#{ m }") }.compact.size == a.size
91
+ end
92
+
93
+
94
+ #--------------------------------------------------
95
+ # Private Methods
96
+ #--------------------------------------------------
97
+ private
98
+
99
+ def option_keys
100
+ [:content, :style, :font, :color, :size, :bold, :italic, :underline, :bgcolor, :highlight_color, :vertical_align]
101
+ end
102
+
103
+ def method_missing(method, *args, &block)
104
+ # I'm on the fence with respect to this implementation. We're ignoring
105
+ # :method_missing errors to allow syntax flexibility for paragraph-type
106
+ # models. The issue is the syntax format of those models--the way we pass
107
+ # the content value as a special argument--coupled with the model's
108
+ # ability to accept nested instructions.
109
+ #
110
+ # By ignoring method missing errors here, we can pass the entire paragraph
111
+ # block in the initial, built-in call to :text.
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,89 @@
1
+ require 'caracal/core/models/namespace_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to registering and
9
+ # retrieving namespaces.
10
+ #
11
+ module Namespaces
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Class Methods
17
+ #-------------------------------------------------------------
18
+
19
+ def self.default_namespaces
20
+ [
21
+ { prefix: 'xmlns:mc', href: 'http://schemas.openxmlformats.org/markup-compatibility/2006' },
22
+ { prefix: 'xmlns:o', href: 'urn:schemas-microsoft-com:office:office' },
23
+ { prefix: 'xmlns:r', href: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' },
24
+ { prefix: 'xmlns:m', href: 'http://schemas.openxmlformats.org/officeDocument/2006/math' },
25
+ { prefix: 'xmlns:v', href: 'urn:schemas-microsoft-com:vml' },
26
+ { prefix: 'xmlns:wp', href: 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing' },
27
+ { prefix: 'xmlns:w10', href: 'urn:schemas-microsoft-com:office:word' },
28
+ { prefix: 'xmlns:w', href: 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' },
29
+ { prefix: 'xmlns:wne', href: 'http://schemas.microsoft.com/office/word/2006/wordml' },
30
+ { prefix: 'xmlns:sl', href: 'http://schemas.openxmlformats.org/schemaLibrary/2006/main' },
31
+ { prefix: 'xmlns:a', href: 'http://schemas.openxmlformats.org/drawingml/2006/main' },
32
+ { prefix: 'xmlns:pic', href: 'http://schemas.openxmlformats.org/drawingml/2006/picture' },
33
+ { prefix: 'xmlns:c', href: 'http://schemas.openxmlformats.org/drawingml/2006/chart' },
34
+ { prefix: 'xmlns:lc', href: 'http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas' },
35
+ { prefix: 'xmlns:dgm', href: 'http://schemas.openxmlformats.org/drawingml/2006/diagram' }
36
+ ]
37
+ end
38
+
39
+
40
+ #-------------------------------------------------------------
41
+ # Public Methods
42
+ #-------------------------------------------------------------
43
+
44
+ #============== ATTRIBUTES ==========================
45
+
46
+ def namespace(options={}, &block)
47
+ model = Caracal::Core::Models::NamespaceModel.new(options, &block)
48
+ if model.valid?
49
+ ns = register_namespace(model)
50
+ else
51
+ raise Caracal::Errors::InvalidModelError, 'namespace must specify the :prefix and :href attributes.'
52
+ end
53
+ ns
54
+ end
55
+
56
+
57
+ #============== GETTERS =============================
58
+
59
+ def namespaces
60
+ @namespaces ||= []
61
+ end
62
+
63
+ def find_namespace(prefix)
64
+ namespaces.find { |ns| ns.matches?(prefix) }
65
+ end
66
+
67
+
68
+ #============== REGISTRATION ========================
69
+
70
+ def register_namespace(model)
71
+ unless ns = find_namespace(model.namespace_prefix)
72
+ namespaces << model
73
+ ns = model
74
+ end
75
+ ns
76
+ end
77
+
78
+ def unregister_namespace(prefix)
79
+ if ns = find_namespace(prefix)
80
+ namespaces.delete(ns)
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,29 @@
1
+ require 'caracal/core/models/page_break_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+
7
+ # This module encapsulates all the functionality related to adding page
8
+ # breaks to the document.
9
+ #
10
+ module PageBreaks
11
+ def self.included(base)
12
+ base.class_eval do
13
+
14
+ #-------------------------------------------------------------
15
+ # Public Methods
16
+ #-------------------------------------------------------------
17
+
18
+ def page
19
+ model = Caracal::Core::Models::PageBreakModel.new()
20
+ contents << model
21
+ model
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,58 @@
1
+ require 'caracal/core/models/page_number_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to setting the
9
+ # document's page number behavior.
10
+ #
11
+ module PageNumbers
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Configuration
17
+ #-------------------------------------------------------------
18
+
19
+ # constants
20
+ const_set(:DEFAULT_PAGE_NUMBER_ALIGN, :center)
21
+
22
+ # accessors
23
+ attr_reader :page_number_align
24
+ attr_reader :page_number_label
25
+ attr_reader :page_number_label_size
26
+ attr_reader :page_number_number_size
27
+ attr_reader :page_number_show
28
+
29
+
30
+ #-------------------------------------------------------------
31
+ # Public Methods
32
+ #-------------------------------------------------------------
33
+
34
+ # This method controls whether and how page numbers are displayed
35
+ # on the document.
36
+ #
37
+ def page_numbers(*args, &block)
38
+ options = Caracal::Utilities.extract_options!(args)
39
+ options.merge!({ show: !!args.first }) unless args.first.nil? # careful: just `args.first` is falsey
40
+
41
+ model = Caracal::Core::Models::PageNumberModel.new(options, &block)
42
+ if model.valid?
43
+ @page_number_align = model.page_number_align
44
+ @page_number_label = model.page_number_label
45
+ @page_number_label_size = model.page_number_label_size
46
+ @page_number_number_size = model.page_number_number_size
47
+ @page_number_show = model.page_number_show
48
+ else
49
+ raise Caracal::Errors::InvalidModelError, 'page_numbers :align parameter must be :left, :center, or :right'
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+
57
+ end
58
+ end