caracal_the_curve 1.4.1 → 1.4.3

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/caracal.gemspec +2 -2
  3. data/lib/caracal/core/fields.rb +34 -0
  4. data/lib/caracal/core/footer.rb +33 -0
  5. data/lib/caracal/core/header.rb +32 -0
  6. data/lib/caracal/core/models/field_model.rb +124 -0
  7. data/lib/caracal/core/models/footer_model.rb +42 -0
  8. data/lib/caracal/core/models/header_model.rb +42 -0
  9. data/lib/caracal/core/models/page_flip_model.rb +41 -0
  10. data/lib/caracal/core/models/paragraph_model.rb +15 -0
  11. data/lib/caracal/core/models/relationship_model.rb +1 -0
  12. data/lib/caracal/core/models/style_model.rb +6 -2
  13. data/lib/caracal/core/models/table_of_contents_model.rb +81 -0
  14. data/lib/caracal/core/page_flips.rb +34 -0
  15. data/lib/caracal/core/relationships.rb +1 -0
  16. data/lib/caracal/core/styles.rb +7 -7
  17. data/lib/caracal/core/table_of_contents.rb +34 -0
  18. data/lib/caracal/document.rb +26 -0
  19. data/lib/caracal/renderers/content_types_renderer.rb +1 -0
  20. data/lib/caracal/renderers/document_renderer.rb +105 -4
  21. data/lib/caracal/renderers/footer_renderer.rb +42 -29
  22. data/lib/caracal/renderers/header_renderer.rb +61 -0
  23. data/lib/caracal/renderers/settings_renderer.rb +2 -1
  24. data/lib/caracal/renderers/styles_renderer.rb +2 -0
  25. data/lib/caracal/version.rb +1 -1
  26. data/lib/caracal.rb +24 -0
  27. data/spec/lib/caracal/core/fields_spec.rb +25 -0
  28. data/spec/lib/caracal/core/footer_spec.rb +31 -0
  29. data/spec/lib/caracal/core/header_spec.rb +31 -0
  30. data/spec/lib/caracal/core/models/footer_model_spec.rb +40 -0
  31. data/spec/lib/caracal/core/models/header_model_spec.rb +40 -0
  32. data/spec/lib/caracal/core/models/page_flip_model_spec.rb +34 -0
  33. data/spec/lib/caracal/core/models/paragraph_model_spec.rb +18 -1
  34. data/spec/lib/caracal/core/models/style_model_spec.rb +8 -1
  35. data/spec/lib/caracal/core/models/table_of_contents_model_spec.rb +89 -0
  36. data/spec/lib/caracal/core/page_flip_spec.rb +27 -0
  37. data/spec/lib/caracal/core/relationships_spec.rb +2 -2
  38. metadata +34 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f5d4a9ccb930cc2eb43e169140f9b47626f4713afa525322a0c7f864603875a
4
- data.tar.gz: 41cf0b1af0c1f09f710380f779d12f9509c207b99eddfbe2b69f4dc4b3ca0f03
3
+ metadata.gz: e6da04caa966ebd5e16ea4750f12f96ac92671bc5398040ffac7634c0ace0430
4
+ data.tar.gz: d22baa3abb96b9a569864e414542d5aacdcff42c42cf71586c95a5c4e855afd0
5
5
  SHA512:
6
- metadata.gz: e993e86c44852e6ac98f8aa4cc4c777e954ccb09bbe7742fba541fc71d534e11fffae8368d2ad9ec5b02240a20406fa504fd0a8b1dd6050140123b642ac7e196
7
- data.tar.gz: 00acddad9a31fef96b827b1874eef89d05f92e86393ab741c9ed73840eb8e4cfde0f4668ca30f7d458f71e280398423cabe4cfb77456f6ebf1c4c7857e90b99d
6
+ metadata.gz: 700413b3717f24148a68d6d211a817f70dbf1991871942981c8eada98be9a63d629c88c281e8bdb55b328536bccdb1e1bbec23e64057c86648973630aaa9aad9
7
+ data.tar.gz: 742d487ca24ab7f5aba5a71b844fe9ac42a3a15bde8ba327d6d3b8b7a396dbba5e62036436e71541e1ac13baf5461096164b195b3688b8b685109bbb51d896ea
data/caracal.gemspec CHANGED
@@ -6,8 +6,8 @@ require 'caracal/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'caracal_the_curve'
8
8
  spec.version = Caracal::VERSION
9
- spec.authors = ['Trade Infomatics', 'John Dugan']
10
- spec.email = ['jpdugan@gmail.com']
9
+ spec.authors = ['Trade Infomatics', 'John Dugan', 'James Ridgway', 'Matthew Barber']
10
+ spec.email = ['jpdugan@gmail.com', 'james.ridgway@tccs.io', 'matthew.barber@tccs.io']
11
11
  spec.summary = %q{ Fast, professional Microsoft Word (docx) writer for Ruby. }
12
12
  spec.description = %q{ Caracal is a pure Ruby Microsoft Word generation library that produces professional quality MSWord documents (docx) using a simple, HTML-style DSL. }
13
13
  spec.homepage = 'https://github.com/trade-informatics/caracal'
@@ -0,0 +1,34 @@
1
+ require 'caracal/core/models/field_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to fields
9
+ #
10
+ module Fields
11
+ def self.included(base)
12
+ base.class_eval do
13
+
14
+ #-------------------------------------------------------------
15
+ # Public Methods
16
+ #-------------------------------------------------------------
17
+
18
+ def field(*args, &block)
19
+ options = Caracal::Utilities.extract_options!(args)
20
+ options.merge!({ type: args.first }) if args.first
21
+
22
+ model = Caracal::Core::Models::FieldModel.new(options, &block)
23
+
24
+ if model.valid?
25
+ contents << model
26
+ end
27
+
28
+ model
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ require 'caracal/core/models/footer_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to adding a
9
+ # footer on every page of the document.
10
+ #
11
+ module Footer
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Public Methods
17
+ #-------------------------------------------------------------
18
+
19
+ def footer(*args, &block)
20
+ options = Caracal::Utilities.extract_options!(args)
21
+
22
+ model = Caracal::Core::Models::FooterModel.new(options, &block)
23
+
24
+ @footer_content = model
25
+
26
+ model
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ require 'caracal/core/models/header_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to adding a header
9
+ # to every page of the document.
10
+ #
11
+ module Header
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Public Methods
17
+ #-------------------------------------------------------------
18
+
19
+ def header(*args, &block)
20
+ options = Caracal::Utilities.extract_options!(args)
21
+
22
+ model = Caracal::Core::Models::HeaderModel.new(options, &block)
23
+
24
+ @header_content = model
25
+
26
+ model
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,124 @@
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 FieldModel < BaseModel
12
+
13
+ #--------------------------------------------------
14
+ # Configuration
15
+ #--------------------------------------------------
16
+
17
+ # constants
18
+ const_set(:TYPE_MAP, { page: 'PAGE', numpages: 'NUMPAGES' })
19
+
20
+ # accessors
21
+ attr_reader :field_dirty
22
+ attr_reader :field_type
23
+ attr_reader :field_style
24
+ attr_reader :field_font
25
+ attr_reader :field_color
26
+ attr_reader :field_size
27
+ attr_reader :field_bold
28
+ attr_reader :field_italic
29
+ attr_reader :field_underline
30
+ attr_reader :field_bgcolor
31
+ attr_reader :field_highlight_color
32
+ attr_reader :field_vertical_align
33
+
34
+ #-------------------------------------------------------------
35
+ # Public Class Methods
36
+ #-------------------------------------------------------------
37
+
38
+ def self.formatted_type(type)
39
+ TYPE_MAP.fetch(type.to_s.to_sym)
40
+ end
41
+
42
+
43
+ #-------------------------------------------------------------
44
+ # Public Instance Methods
45
+ #-------------------------------------------------------------
46
+
47
+ #=============== GETTERS ==============================
48
+
49
+ def formatted_type
50
+ self.class.formatted_type(field_type)
51
+ end
52
+
53
+ #========== GETTERS ===============================
54
+
55
+ # .run_attributes
56
+ def run_attributes
57
+ {
58
+ style: field_style,
59
+ font: field_font,
60
+ color: field_color,
61
+ size: field_size,
62
+ bold: field_bold,
63
+ italic: field_italic,
64
+ underline: field_underline,
65
+ bgcolor: field_bgcolor,
66
+ highlight_color: field_highlight_color,
67
+ vertical_align: field_vertical_align
68
+ }
69
+ end
70
+
71
+
72
+ #========== SETTERS ===============================
73
+
74
+ # booleans
75
+ [:bold, :italic, :underline].each do |m|
76
+ define_method "#{ m }" do |value|
77
+ instance_variable_set("@field_#{ m }", !!value)
78
+ end
79
+ end
80
+
81
+ # integers
82
+ [:size].each do |m|
83
+ define_method "#{ m }" do |value|
84
+ instance_variable_set("@field_#{ m }", value.to_i)
85
+ end
86
+ end
87
+
88
+ # strings
89
+ [:bgcolor, :color, :dirty, :font, :highlight_color, :style, :type].each do |m|
90
+ define_method "#{ m }" do |value|
91
+ instance_variable_set("@field_#{ m }", value.to_s)
92
+ end
93
+ end
94
+
95
+ # symbols
96
+ [:vertical_align].each do |m|
97
+ define_method "#{ m }" do |value|
98
+ instance_variable_set("@field_#{ m }", value.to_s.to_sym)
99
+ end
100
+ end
101
+
102
+
103
+ #========== VALIDATION ============================
104
+
105
+ def valid?
106
+ a = [:type]
107
+ a.map { |m| send("field_#{ m }") }.compact.size == a.size
108
+ end
109
+
110
+
111
+ #--------------------------------------------------
112
+ # Private Methods
113
+ #--------------------------------------------------
114
+ private
115
+
116
+ def option_keys
117
+ [:type, :style, :font, :color, :size, :bold, :italic, :underline, :bgcolor, :highlight_color, :vertical_align]
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,42 @@
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 FooterModel < BaseModel
14
+
15
+ #-------------------------------------------------------------
16
+ # Configuration
17
+ #-------------------------------------------------------------
18
+
19
+ # initialization
20
+ def initialize(options={}, &block)
21
+ super options, &block
22
+ end
23
+
24
+ #-------------------------------------------------------------
25
+ # Public Methods
26
+ #-------------------------------------------------------------
27
+
28
+ #=============== DATA ACCESSORS =======================
29
+
30
+ def contents
31
+ @contents ||= []
32
+ end
33
+
34
+ #=============== VALIDATION ===========================
35
+
36
+ def valid?
37
+ contents.size > 0
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
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 HeaderModel < BaseModel
14
+
15
+ #-------------------------------------------------------------
16
+ # Configuration
17
+ #-------------------------------------------------------------
18
+
19
+ # initialization
20
+ def initialize(options={}, &block)
21
+ super options, &block
22
+ end
23
+
24
+ #-------------------------------------------------------------
25
+ # Public Methods
26
+ #-------------------------------------------------------------
27
+
28
+ #=============== DATA ACCESSORS =======================
29
+
30
+ def contents
31
+ @contents ||= []
32
+ end
33
+
34
+ #=============== VALIDATION ===========================
35
+
36
+ def valid?
37
+ contents.size > 0
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
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 tables via their data
8
+ # collections.
9
+ #
10
+ class PageFlipModel < BaseModel
11
+
12
+ #-------------------------------------------------------------
13
+ # Configuration
14
+ #-------------------------------------------------------------
15
+
16
+ # initialization
17
+ def initialize(options={}, &block)
18
+ super options, &block
19
+ end
20
+
21
+ #-------------------------------------------------------------
22
+ # Public Methods
23
+ #-------------------------------------------------------------
24
+
25
+ #=============== DATA ACCESSORS =======================
26
+
27
+ # .contents
28
+ def contents
29
+ @contents ||= []
30
+ end
31
+
32
+ #=============== VALIDATION ===========================
33
+
34
+ # .valid?
35
+ def valid?
36
+ contents.size > 0
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,6 +2,7 @@ require 'caracal/core/models/base_model'
2
2
  require 'caracal/core/models/bookmark_model'
3
3
  require 'caracal/core/models/link_model'
4
4
  require 'caracal/core/models/text_model'
5
+ require 'caracal/core/models/field_model'
5
6
  require 'caracal/errors'
6
7
 
7
8
 
@@ -126,6 +127,20 @@ module Caracal
126
127
  model
127
128
  end
128
129
 
130
+ # .page_num
131
+ def field(*args, &block)
132
+ options = Caracal::Utilities.extract_options!(args)
133
+ options = options.merge({ type: args[0] })
134
+
135
+ model = Caracal::Core::Models::FieldModel.new(options, &block)
136
+ if model.valid?
137
+ runs << model
138
+ else
139
+ raise Caracal::Errors::InvalidModelError, ':page_num method must receive a string for the display text.'
140
+ end
141
+ model
142
+ end
143
+
129
144
  # .link
130
145
  def link(*args, &block)
131
146
  options = Caracal::Utilities.extract_options!(args)
@@ -18,6 +18,7 @@ module Caracal
18
18
  TYPE_MAP = {
19
19
  font: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable',
20
20
  footer: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer',
21
+ header: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header',
21
22
  image: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
22
23
  link: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
23
24
  numbering: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering',
@@ -28,6 +28,7 @@ module Caracal
28
28
  const_set(:DEFAULT_STYLE_BOTTOM, 0) # 0.0in in twips
29
29
  const_set(:DEFAULT_STYLE_BASE, 'Normal')
30
30
  const_set(:DEFAULT_STYLE_NEXT, 'Normal')
31
+ const_set(:DEFAULT_STYLE_OUTLINE, 9) # no level
31
32
 
32
33
  # accessors
33
34
  attr_reader :style_default
@@ -50,6 +51,7 @@ module Caracal
50
51
  attr_reader :style_indent_left
51
52
  attr_reader :style_indent_right
52
53
  attr_reader :style_indent_first
54
+ attr_reader :style_outline
53
55
 
54
56
  # initialization
55
57
  def initialize(options={}, &block)
@@ -72,6 +74,7 @@ module Caracal
72
74
  @style_top ||= DEFAULT_STYLE_TOP
73
75
  @style_bottom ||= DEFAULT_STYLE_BOTTOM
74
76
  @style_line ||= DEFAULT_STYLE_LINE
77
+ @style_outline ||= DEFAULT_STYLE_OUTLINE
75
78
  end
76
79
  end
77
80
 
@@ -97,7 +100,7 @@ module Caracal
97
100
  end
98
101
 
99
102
  # strings
100
- [:id, :type, :name, :color, :font].each do |m|
103
+ [:id, :type, :name, :color, :font, :outline].each do |m|
101
104
  define_method "#{ m }" do |value|
102
105
  instance_variable_set("@style_#{ m }", value.to_s)
103
106
  end
@@ -155,7 +158,8 @@ module Caracal
155
158
  :align,
156
159
  :indent_left,
157
160
  :indent_right,
158
- :indent_first ]
161
+ :indent_first,
162
+ :outline ]
159
163
  end
160
164
 
161
165
  end
@@ -0,0 +1,81 @@
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 TableOfContentsModel < BaseModel
12
+
13
+ #--------------------------------------------------
14
+ # Configuration
15
+ #--------------------------------------------------
16
+
17
+ # constants
18
+ const_set(:DEFAULT_OPTS, 'TOC \o "1-1" \h \z \u \t "Heading 5,1"')
19
+ const_set(:DEFAULT_SIZE, 32)
20
+ const_set(:DEFAULT_TITLE, 'Table of Contents')
21
+
22
+ # accessors
23
+ attr_reader :toc_opts
24
+ attr_reader :toc_size
25
+ attr_reader :toc_title
26
+
27
+ #-------------------------------------------------------------
28
+ # Public Class Methods
29
+ #-------------------------------------------------------------
30
+
31
+ # initialization
32
+ def initialize(options={}, &block)
33
+ @toc_opts ||= DEFAULT_OPTS
34
+ @toc_size ||= DEFAULT_SIZE
35
+ @toc_title ||= DEFAULT_TITLE
36
+ super options, &block
37
+ end
38
+
39
+ #-------------------------------------------------------------
40
+ # Public Instance Methods
41
+ #-------------------------------------------------------------
42
+
43
+ #=============== GETTERS ==============================
44
+
45
+ #========== GETTERS ===============================
46
+
47
+ #========== SETTERS ===============================
48
+
49
+ # integers
50
+ [:size].each do |m|
51
+ define_method "#{ m }" do |value|
52
+ instance_variable_set("@toc_#{ m }", value.to_i)
53
+ end
54
+ end
55
+
56
+ # strings
57
+ [:title, :opts].each do |m|
58
+ define_method "#{ m }" do |value|
59
+ instance_variable_set("@toc_#{ m }", value.to_s)
60
+ end
61
+ end
62
+
63
+ #========== VALIDATION ============================
64
+
65
+ def valid?
66
+ a = [:opts, :size, :title]
67
+ a.map { |m| send("toc_#{ m }") }.compact.size == a.size
68
+ end
69
+
70
+ #--------------------------------------------------
71
+ # Private Methods
72
+ #--------------------------------------------------
73
+ private
74
+
75
+ def option_keys
76
+ [:opts, :size, :title]
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,34 @@
1
+ require 'caracal/core/models/page_flip_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to flipping
9
+ # specific page contents
10
+ #
11
+ module PageFlips
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Public Methods
17
+ #-------------------------------------------------------------
18
+
19
+ def page_flip(*args, &block)
20
+ options = Caracal::Utilities.extract_options!(args)
21
+
22
+ model = Caracal::Core::Models::PageFlipModel.new(options, &block)
23
+
24
+ if model.valid?
25
+ contents << model
26
+ end
27
+
28
+ model
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -27,6 +27,7 @@ module Caracal
27
27
  [
28
28
  { target: 'fontTable.xml', type: :font },
29
29
  { target: 'footer1.xml', type: :footer },
30
+ { target: 'header1.xml', type: :header },
30
31
  { target: 'numbering.xml', type: :numbering },
31
32
  { target: 'settings.xml', type: :setting },
32
33
  { target: 'styles.xml', type: :style }
@@ -19,12 +19,12 @@ module Caracal
19
19
  def self.default_styles
20
20
  [
21
21
  { id: 'Normal', name: 'normal', font: 'Arial', size: 20, line: 320, color: '333333' },
22
- { id: 'Heading1', name: 'heading 1', font: 'Palatino', size: 36, bottom: 120 },
23
- { id: 'Heading2', name: 'heading 2', font: 'Arial', size: 26, top: 120, bottom: 160, bold: true },
24
- { id: 'Heading3', name: 'heading 3', font: 'Arial', size: 24, top: 120, bottom: 160, bold: true, italic: true, color: '666666' },
25
- { id: 'Heading4', name: 'heading 4', font: 'Palatino', size: 24, top: 120, bottom: 120, bold: true },
26
- { id: 'Heading5', name: 'heading 5', font: 'Arial', size: 22, top: 120, bottom: 120, bold: true },
27
- { id: 'Heading6', name: 'heading 6', font: 'Arial', size: 22, top: 120, bottom: 120, underline: true, italic: true, color: '666666' },
22
+ { id: 'Heading1', name: 'heading 1', font: 'Palatino', size: 36, outline: 0, bottom: 120},
23
+ { id: 'Heading2', name: 'heading 2', font: 'Arial', size: 26, outline: 1, top: 120, bottom: 160, bold: true },
24
+ { id: 'Heading3', name: 'heading 3', font: 'Arial', size: 24, outline: 2, top: 120, bottom: 160, bold: true, italic: true, color: '666666' },
25
+ { id: 'Heading4', name: 'heading 4', font: 'Palatino', size: 24, outline: 3, top: 120, bottom: 120, bold: true },
26
+ { id: 'Heading5', name: 'heading 5', font: 'Arial', size: 22, outline: 4, top: 120, bottom: 120, bold: true },
27
+ { id: 'Heading6', name: 'heading 6', font: 'Arial', size: 22, outline: 5, top: 120, bottom: 120, underline: true, italic: true, color: '666666' },
28
28
  { id: 'Title', name: 'title', font: 'Palatino', size: 60 },
29
29
  { id: 'Subtitle', name: 'subtitle', font: 'Arial', size: 28, top: 60 }
30
30
  ]
@@ -83,4 +83,4 @@ module Caracal
83
83
  end
84
84
 
85
85
  end
86
- end
86
+ end
@@ -0,0 +1,34 @@
1
+ require 'caracal/core/models/table_of_contents_model'
2
+ require 'caracal/errors'
3
+
4
+
5
+ module Caracal
6
+ module Core
7
+
8
+ # This module encapsulates all the functionality related to table of
9
+ # contents
10
+ #
11
+ module TableOfContents
12
+ def self.included(base)
13
+ base.class_eval do
14
+
15
+ #-------------------------------------------------------------
16
+ # Public Methods
17
+ #-------------------------------------------------------------
18
+
19
+ def table_of_contents(*args, &block)
20
+ options = Caracal::Utilities.extract_options!(args)
21
+
22
+ model = Caracal::Core::Models::TableOfContentsModel.new(options, &block)
23
+
24
+ if model.valid?
25
+ contents << model
26
+ end
27
+
28
+ model
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end