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
data/Rakefile
ADDED
data/caracal.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'caracal/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'caracal_the_curve'
|
8
|
+
spec.version = Caracal::VERSION
|
9
|
+
spec.authors = ['Trade Infomatics', 'John Dugan']
|
10
|
+
spec.email = ['jpdugan@gmail.com']
|
11
|
+
spec.summary = %q{ Fast, professional Microsoft Word (docx) writer for Ruby. }
|
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
|
+
spec.homepage = 'https://github.com/trade-informatics/caracal'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'nokogiri', '~> 1.6'
|
22
|
+
spec.add_dependency 'rubyzip', ['>= 1.1.0', '< 3.0']
|
23
|
+
spec.add_dependency 'tilt', '>= 1.4'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 2.4'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'caracal/core/models/bookmark_model'
|
2
|
+
require 'caracal/errors'
|
3
|
+
|
4
|
+
|
5
|
+
module Caracal
|
6
|
+
module Core
|
7
|
+
|
8
|
+
# This module encapsulates all the functionality related to adding
|
9
|
+
# bookmarks to the document.
|
10
|
+
#
|
11
|
+
module Bookmarks
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
#------------------------------------------------
|
16
|
+
# Public Methods
|
17
|
+
#------------------------------------------------
|
18
|
+
|
19
|
+
#========== BOOKMARKS ===========================
|
20
|
+
|
21
|
+
def bookmark_start(*args, &block)
|
22
|
+
options = Caracal::Utilities.extract_options!(args)
|
23
|
+
options.merge!({ start: true})
|
24
|
+
|
25
|
+
model = Caracal::Core::Models::BookmarkModel.new(options, &block)
|
26
|
+
if model.valid?
|
27
|
+
contents << model
|
28
|
+
else
|
29
|
+
raise Caracal::Errors::InvalidModelError, 'Bookmark starting tags require an id and a name.'
|
30
|
+
end
|
31
|
+
model
|
32
|
+
end
|
33
|
+
|
34
|
+
def bookmark_end(*args, &block)
|
35
|
+
options = Caracal::Utilities.extract_options!(args)
|
36
|
+
options.merge!({ start: false})
|
37
|
+
|
38
|
+
model = Caracal::Core::Models::BookmarkModel.new(options, &block)
|
39
|
+
if model.valid?
|
40
|
+
contents << model
|
41
|
+
else
|
42
|
+
raise Caracal::Errors::InvalidModelError, 'Bookmark ending tags require an id.'
|
43
|
+
end
|
44
|
+
model
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'caracal/core/models/custom_property_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 custom properties.
|
10
|
+
#
|
11
|
+
module CustomProperties
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
# Public Methods
|
17
|
+
#-------------------------------------------------------------
|
18
|
+
|
19
|
+
# This method controls the custom properties.
|
20
|
+
#
|
21
|
+
def custom_property(options={}, &block)
|
22
|
+
model = Caracal::Core::Models::CustomPropertyModel.new(options, &block)
|
23
|
+
if model.valid?
|
24
|
+
register_property(model)
|
25
|
+
end
|
26
|
+
model
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
#============== GETTERS =============================
|
31
|
+
|
32
|
+
def custom_props
|
33
|
+
@custom_props ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
#============== REGISTRATION ========================
|
38
|
+
|
39
|
+
def register_property(model)
|
40
|
+
custom_props << model
|
41
|
+
model
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Caracal
|
2
|
+
module Core
|
3
|
+
|
4
|
+
# This module encapsulates all the functionality related to setting the
|
5
|
+
# document's name.
|
6
|
+
#
|
7
|
+
module FileName
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
|
11
|
+
#-------------------------------------------------------------
|
12
|
+
# Configuration
|
13
|
+
#-------------------------------------------------------------
|
14
|
+
|
15
|
+
# constants
|
16
|
+
const_set(:DEFAULT_FILE_NAME, 'caracal.docx')
|
17
|
+
|
18
|
+
# accessors
|
19
|
+
attr_reader :name
|
20
|
+
attr_reader :path
|
21
|
+
|
22
|
+
|
23
|
+
#-------------------------------------------------------------
|
24
|
+
# Public Methods
|
25
|
+
#-------------------------------------------------------------
|
26
|
+
|
27
|
+
# This method sets the name of the output file. Defaults
|
28
|
+
# to the name of the library.
|
29
|
+
#
|
30
|
+
def file_name(value=nil)
|
31
|
+
v = value.to_s.strip
|
32
|
+
a = v.split('/')
|
33
|
+
|
34
|
+
@name = (v == '') ? self.class::DEFAULT_FILE_NAME : a.last
|
35
|
+
@path = (a.size > 1) ? v : "./#{ v }"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'caracal/core/models/font_model'
|
2
|
+
require 'caracal/errors'
|
3
|
+
|
4
|
+
|
5
|
+
module Caracal
|
6
|
+
module Core
|
7
|
+
|
8
|
+
# This module encapsulates all the functionality related to registering
|
9
|
+
# fonts.
|
10
|
+
#
|
11
|
+
module Fonts
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
# Class Methods
|
17
|
+
#-------------------------------------------------------------
|
18
|
+
|
19
|
+
def self.default_fonts
|
20
|
+
[
|
21
|
+
{ name: 'Arial' },
|
22
|
+
{ name: 'Trebuchet MS' }
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
#-------------------------------------------------------------
|
28
|
+
# Public Methods
|
29
|
+
#-------------------------------------------------------------
|
30
|
+
|
31
|
+
#============== ATTRIBUTES ==========================
|
32
|
+
|
33
|
+
def font(options={}, &block)
|
34
|
+
model = Caracal::Core::Models::FontModel.new(options, &block)
|
35
|
+
|
36
|
+
if model.valid?
|
37
|
+
register_font(model)
|
38
|
+
else
|
39
|
+
raise Caracal::Errors::InvalidModelError, 'font must specify the :name attribute.'
|
40
|
+
end
|
41
|
+
model
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
#============== GETTERS =============================
|
46
|
+
|
47
|
+
def fonts
|
48
|
+
@fonts ||= []
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_font(name)
|
52
|
+
fonts.find { |f| f.matches?(name) }
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
#============== REGISTRATION ========================
|
57
|
+
|
58
|
+
def register_font(model)
|
59
|
+
unregister_font(model.font_name)
|
60
|
+
fonts << model
|
61
|
+
model
|
62
|
+
end
|
63
|
+
|
64
|
+
def unregister_font(name)
|
65
|
+
if f = find_font(name)
|
66
|
+
fonts.delete(f)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'caracal/core/models/iframe_model'
|
2
|
+
require 'caracal/errors'
|
3
|
+
|
4
|
+
|
5
|
+
module Caracal
|
6
|
+
module Core
|
7
|
+
|
8
|
+
# This module encapsulates all the functionality related to inserting
|
9
|
+
# word document snippets into the document.
|
10
|
+
#
|
11
|
+
module IFrames
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
# Public Methods
|
17
|
+
#-------------------------------------------------------------
|
18
|
+
|
19
|
+
def iframe(options={}, &block)
|
20
|
+
model = Caracal::Core::Models::IFrameModel.new(options, &block)
|
21
|
+
if model.valid?
|
22
|
+
model.preprocess!
|
23
|
+
model.namespaces.each do |(prefix, href)|
|
24
|
+
namespace({ prefix: prefix, href: href })
|
25
|
+
end
|
26
|
+
model.ignorables.each do |prefix|
|
27
|
+
ignorable(prefix)
|
28
|
+
end
|
29
|
+
|
30
|
+
contents << model
|
31
|
+
else
|
32
|
+
raise Caracal::Errors::InvalidModelError, 'IFrameModel requires either the :url or :data argument.'
|
33
|
+
end
|
34
|
+
model
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Caracal
|
2
|
+
module Core
|
3
|
+
|
4
|
+
# This module encapsulates all the functionality related to registering and
|
5
|
+
# retrieving ignorable namespaces.
|
6
|
+
#
|
7
|
+
module Ignorables
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
|
11
|
+
#-------------------------------------------------------------
|
12
|
+
# Public Methods
|
13
|
+
#-------------------------------------------------------------
|
14
|
+
|
15
|
+
#============== ATTRIBUTES ==========================
|
16
|
+
|
17
|
+
def ignorable(prefix)
|
18
|
+
register_ignorable(prefix)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
#============== GETTERS =============================
|
23
|
+
|
24
|
+
def ignorables
|
25
|
+
@ignorables ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
#============== REGISTRATION ========================
|
30
|
+
|
31
|
+
def register_ignorable(prefix)
|
32
|
+
unless ignorables.include?(prefix)
|
33
|
+
ignorables << prefix
|
34
|
+
prefix
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def unregister_ignorable(prefix)
|
39
|
+
ignorables.delete(prefix)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'caracal/core/models/image_model'
|
2
|
+
require 'caracal/errors'
|
3
|
+
|
4
|
+
|
5
|
+
module Caracal
|
6
|
+
module Core
|
7
|
+
|
8
|
+
# This module encapsulates all the functionality related to adding
|
9
|
+
# images to the document.
|
10
|
+
#
|
11
|
+
module Images
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
# Public Methods
|
17
|
+
#-------------------------------------------------------------
|
18
|
+
|
19
|
+
def img(*args, &block)
|
20
|
+
options = Caracal::Utilities.extract_options!(args)
|
21
|
+
options.merge!({ url: args.first }) if args.first
|
22
|
+
|
23
|
+
model = Caracal::Core::Models::ImageModel.new(options, &block)
|
24
|
+
if model.valid?
|
25
|
+
contents << model
|
26
|
+
else
|
27
|
+
raise Caracal::Errors::InvalidModelError, 'Images require an URL and positive size/margin values.'
|
28
|
+
end
|
29
|
+
model
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'caracal/core/models/list_style_model'
|
3
|
+
require 'caracal/errors'
|
4
|
+
|
5
|
+
|
6
|
+
module Caracal
|
7
|
+
module Core
|
8
|
+
|
9
|
+
# This module encapsulates all the functionality related to defining
|
10
|
+
# list styles.
|
11
|
+
#
|
12
|
+
module ListStyles
|
13
|
+
def self.included(base)
|
14
|
+
base.class_eval do
|
15
|
+
|
16
|
+
#-------------------------------------------------------------
|
17
|
+
# Class Methods
|
18
|
+
#-------------------------------------------------------------
|
19
|
+
|
20
|
+
def self.default_list_styles
|
21
|
+
[
|
22
|
+
{ type: :ordered, level: 0, format: 'decimal', value: '%1.', left: 720, indent: 360 },
|
23
|
+
{ type: :ordered, level: 1, format: 'lowerLetter', value: '%2.', left: 1440, indent: 1080 },
|
24
|
+
{ type: :ordered, level: 2, format: 'lowerRoman', value: '%3.', left: 2160, indent: 1800, align: :right },
|
25
|
+
{ type: :ordered, level: 3, format: 'decimal', value: '%4.', left: 2880, indent: 2520 },
|
26
|
+
{ type: :ordered, level: 4, format: 'lowerLetter', value: '%5.', left: 3600, indent: 3240 },
|
27
|
+
{ type: :ordered, level: 5, format: 'lowerRoman', value: '%6.', left: 4320, indent: 3960, align: :right },
|
28
|
+
{ type: :ordered, level: 6, format: 'decimal', value: '%7.', left: 5040, indent: 4680 },
|
29
|
+
{ type: :ordered, level: 7, format: 'lowerLetter', value: '%8.', left: 5760, indent: 5400 },
|
30
|
+
{ type: :ordered, level: 8, format: 'lowerRoman', value: '%9.', left: 6480, indent: 6120, align: :right },
|
31
|
+
|
32
|
+
{ type: :unordered, level: 0, format: 'bullet', value: '●', left: 720, indent: 360 },
|
33
|
+
{ type: :unordered, level: 1, format: 'bullet', value: '○', left: 1440, indent: 1080 },
|
34
|
+
{ type: :unordered, level: 2, format: 'bullet', value: '■', left: 2160, indent: 1800 },
|
35
|
+
{ type: :unordered, level: 3, format: 'bullet', value: '●', left: 2880, indent: 2520 },
|
36
|
+
{ type: :unordered, level: 4, format: 'bullet', value: '○', left: 3600, indent: 3240 },
|
37
|
+
{ type: :unordered, level: 5, format: 'bullet', value: '■', left: 4320, indent: 3960 },
|
38
|
+
{ type: :unordered, level: 6, format: 'bullet', value: '●', left: 5040, indent: 4680 },
|
39
|
+
{ type: :unordered, level: 7, format: 'bullet', value: '○', left: 5760, indent: 5400 },
|
40
|
+
{ type: :unordered, level: 8, format: 'bullet', value: '■', left: 6480, indent: 6120 }
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
#-------------------------------------------------------------
|
46
|
+
# Public Methods
|
47
|
+
#-------------------------------------------------------------
|
48
|
+
|
49
|
+
#============== ATTRIBUTES ==========================
|
50
|
+
|
51
|
+
def list_style(options={}, &block)
|
52
|
+
model = Caracal::Core::Models::ListStyleModel.new(options, &block)
|
53
|
+
|
54
|
+
if model.valid?
|
55
|
+
register_list_style(model)
|
56
|
+
else
|
57
|
+
raise Caracal::Errors::InvalidModelError, 'list style must define a :type, :level, :format, and :value.'
|
58
|
+
end
|
59
|
+
model
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
#============== GETTERS =============================
|
64
|
+
|
65
|
+
def list_styles
|
66
|
+
@list_styles ||= []
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_list_style(type, level)
|
70
|
+
list_styles.find { |s| s.matches?(type, level) }
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
#============== REGISTRATION ========================
|
75
|
+
|
76
|
+
def register_list_style(model)
|
77
|
+
unregister_list_style(model.style_type, model.style_level)
|
78
|
+
list_styles << model
|
79
|
+
model
|
80
|
+
end
|
81
|
+
|
82
|
+
def unregister_list_style(type, level)
|
83
|
+
if s = find_list_style(type, level)
|
84
|
+
list_styles.delete(s)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'caracal/core/models/list_model'
|
2
|
+
require 'caracal/errors'
|
3
|
+
|
4
|
+
|
5
|
+
module Caracal
|
6
|
+
module Core
|
7
|
+
|
8
|
+
# This module encapsulates all the functionality related to adding
|
9
|
+
# horizontal rules to the document.
|
10
|
+
#
|
11
|
+
module Lists
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
#-------------------------------------------------------------
|
16
|
+
# Public Methods
|
17
|
+
#-------------------------------------------------------------
|
18
|
+
|
19
|
+
#============== ATTRIBUTES ==========================
|
20
|
+
|
21
|
+
def ol(options={}, &block)
|
22
|
+
options.merge!({ type: :ordered, level: 0 })
|
23
|
+
|
24
|
+
model = Caracal::Core::Models::ListModel.new(options, &block)
|
25
|
+
if model.valid?
|
26
|
+
contents << model
|
27
|
+
else
|
28
|
+
raise Caracal::Errors::InvalidModelError, 'Ordered lists require at least one list item.'
|
29
|
+
end
|
30
|
+
model
|
31
|
+
end
|
32
|
+
|
33
|
+
def ul(options={}, &block)
|
34
|
+
options.merge!({ type: :unordered, level: 0 })
|
35
|
+
|
36
|
+
model = Caracal::Core::Models::ListModel.new(options, &block)
|
37
|
+
if model.valid?
|
38
|
+
contents << model
|
39
|
+
else
|
40
|
+
raise Caracal::Errors::InvalidModelError, 'Unordered lists require at least one list item.'
|
41
|
+
end
|
42
|
+
model
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
#============== GETTERS ==========================
|
47
|
+
|
48
|
+
def toplevel_lists
|
49
|
+
@toplevel_lists ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Caracal
|
2
|
+
module Core
|
3
|
+
module Models
|
4
|
+
|
5
|
+
# This class encapsulates the logic needed for functions that
|
6
|
+
# do not store or manipulate data.
|
7
|
+
#
|
8
|
+
class BaseModel
|
9
|
+
|
10
|
+
#-------------------------------------------------------------
|
11
|
+
# Configuration
|
12
|
+
#-------------------------------------------------------------
|
13
|
+
|
14
|
+
# initialization
|
15
|
+
def initialize(options={}, &block)
|
16
|
+
options.keep_if { |k,v| option_keys.include? k }
|
17
|
+
options.each do |(key, value)|
|
18
|
+
send(key, value)
|
19
|
+
end
|
20
|
+
|
21
|
+
if block_given?
|
22
|
+
(block.arity < 1) ? instance_eval(&block) : block[self]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
#-------------------------------------------------------------
|
28
|
+
# Public Instance Methods
|
29
|
+
#-------------------------------------------------------------
|
30
|
+
|
31
|
+
#=============== VALIDATION ===========================
|
32
|
+
|
33
|
+
def valid?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
#-------------------------------------------------------------
|
39
|
+
# Private Instance Methods
|
40
|
+
#-------------------------------------------------------------
|
41
|
+
private
|
42
|
+
|
43
|
+
def option_keys
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,86 @@
|
|
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
|
+
# bookmarks.
|
10
|
+
#
|
11
|
+
class BookmarkModel < BaseModel
|
12
|
+
|
13
|
+
#--------------------------------------------------
|
14
|
+
# Configuration
|
15
|
+
#--------------------------------------------------
|
16
|
+
|
17
|
+
# accessors
|
18
|
+
attr_reader :bookmark_start
|
19
|
+
attr_reader :bookmark_id
|
20
|
+
attr_reader :bookmark_name
|
21
|
+
|
22
|
+
|
23
|
+
#--------------------------------------------------
|
24
|
+
# Public Methods
|
25
|
+
#--------------------------------------------------
|
26
|
+
|
27
|
+
#========== GETTERS ===============================
|
28
|
+
|
29
|
+
# .run_attributes
|
30
|
+
def run_attributes
|
31
|
+
{
|
32
|
+
start: bookmark_start,
|
33
|
+
id: bookmark_id,
|
34
|
+
name: bookmark_name
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
#========== SETTERS ===============================
|
40
|
+
|
41
|
+
# booleans
|
42
|
+
[:start].each do |m|
|
43
|
+
define_method "#{ m }" do |value|
|
44
|
+
instance_variable_set("@bookmark_#{ m }", !!value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# strings
|
49
|
+
[:id, :name].each do |m|
|
50
|
+
define_method "#{ m }" do |value|
|
51
|
+
instance_variable_set("@bookmark_#{ m }", value.to_s)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
#========== STATE HELPERS =========================
|
57
|
+
|
58
|
+
def start?
|
59
|
+
!!bookmark_start
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
#========== VALIDATION ============================
|
64
|
+
|
65
|
+
def valid?
|
66
|
+
a = [:id]
|
67
|
+
a << :name if start?
|
68
|
+
|
69
|
+
a.map { |m| send("bookmark_#{ m }") }.compact.size == a.size
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
#--------------------------------------------------
|
74
|
+
# Private Methods
|
75
|
+
#--------------------------------------------------
|
76
|
+
private
|
77
|
+
|
78
|
+
def option_keys
|
79
|
+
[:id, :name, :start]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|