caracal 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +941 -0
  6. data/Rakefile +2 -0
  7. data/caracal.gemspec +27 -0
  8. data/lib/caracal.rb +31 -0
  9. data/lib/caracal/core/file_name.rb +39 -0
  10. data/lib/caracal/core/fonts.rb +75 -0
  11. data/lib/caracal/core/images.rb +37 -0
  12. data/lib/caracal/core/line_breaks.rb +29 -0
  13. data/lib/caracal/core/list_styles.rb +92 -0
  14. data/lib/caracal/core/lists.rb +57 -0
  15. data/lib/caracal/core/models/base_model.rb +51 -0
  16. data/lib/caracal/core/models/border_model.rb +120 -0
  17. data/lib/caracal/core/models/font_model.rb +64 -0
  18. data/lib/caracal/core/models/image_model.rb +118 -0
  19. data/lib/caracal/core/models/line_break_model.rb +15 -0
  20. data/lib/caracal/core/models/link_model.rb +65 -0
  21. data/lib/caracal/core/models/list_item_model.rb +105 -0
  22. data/lib/caracal/core/models/list_model.rb +130 -0
  23. data/lib/caracal/core/models/list_style_model.rb +129 -0
  24. data/lib/caracal/core/models/margin_model.rb +76 -0
  25. data/lib/caracal/core/models/page_break_model.rb +15 -0
  26. data/lib/caracal/core/models/page_number_model.rb +69 -0
  27. data/lib/caracal/core/models/page_size_model.rb +70 -0
  28. data/lib/caracal/core/models/paragraph_model.rb +141 -0
  29. data/lib/caracal/core/models/relationship_model.rb +108 -0
  30. data/lib/caracal/core/models/rule_model.rb +27 -0
  31. data/lib/caracal/core/models/style_model.rb +134 -0
  32. data/lib/caracal/core/models/table_cell_model.rb +155 -0
  33. data/lib/caracal/core/models/table_model.rb +206 -0
  34. data/lib/caracal/core/models/text_model.rb +92 -0
  35. data/lib/caracal/core/page_breaks.rb +29 -0
  36. data/lib/caracal/core/page_numbers.rb +51 -0
  37. data/lib/caracal/core/page_settings.rb +72 -0
  38. data/lib/caracal/core/relationships.rb +90 -0
  39. data/lib/caracal/core/rules.rb +35 -0
  40. data/lib/caracal/core/styles.rb +86 -0
  41. data/lib/caracal/core/tables.rb +41 -0
  42. data/lib/caracal/core/text.rb +73 -0
  43. data/lib/caracal/document.rb +242 -0
  44. data/lib/caracal/errors.rb +23 -0
  45. data/lib/caracal/renderers/app_renderer.rb +41 -0
  46. data/lib/caracal/renderers/content_types_renderer.rb +53 -0
  47. data/lib/caracal/renderers/core_renderer.rb +44 -0
  48. data/lib/caracal/renderers/document_renderer.rb +349 -0
  49. data/lib/caracal/renderers/fonts_renderer.rb +56 -0
  50. data/lib/caracal/renderers/footer_renderer.rb +69 -0
  51. data/lib/caracal/renderers/numbering_renderer.rb +87 -0
  52. data/lib/caracal/renderers/package_relationships_renderer.rb +50 -0
  53. data/lib/caracal/renderers/relationships_renderer.rb +48 -0
  54. data/lib/caracal/renderers/settings_renderer.rb +58 -0
  55. data/lib/caracal/renderers/styles_renderer.rb +163 -0
  56. data/lib/caracal/renderers/xml_renderer.rb +83 -0
  57. data/lib/caracal/version.rb +3 -0
  58. data/lib/tilt/caracal.rb +21 -0
  59. data/spec/lib/caracal/core/file_name_spec.rb +54 -0
  60. data/spec/lib/caracal/core/fonts_spec.rb +119 -0
  61. data/spec/lib/caracal/core/images_spec.rb +25 -0
  62. data/spec/lib/caracal/core/line_breaks_spec.rb +25 -0
  63. data/spec/lib/caracal/core/list_styles_spec.rb +121 -0
  64. data/spec/lib/caracal/core/lists_spec.rb +43 -0
  65. data/spec/lib/caracal/core/models/base_model_spec.rb +38 -0
  66. data/spec/lib/caracal/core/models/border_model_spec.rb +159 -0
  67. data/spec/lib/caracal/core/models/font_model_spec.rb +92 -0
  68. data/spec/lib/caracal/core/models/image_model_spec.rb +192 -0
  69. data/spec/lib/caracal/core/models/line_break_model_spec.rb +21 -0
  70. data/spec/lib/caracal/core/models/link_model_spec.rb +139 -0
  71. data/spec/lib/caracal/core/models/list_item_model_spec.rb +190 -0
  72. data/spec/lib/caracal/core/models/list_model_spec.rb +178 -0
  73. data/spec/lib/caracal/core/models/list_style_model_spec.rb +212 -0
  74. data/spec/lib/caracal/core/models/margin_model_spec.rb +111 -0
  75. data/spec/lib/caracal/core/models/page_break_model_spec.rb +21 -0
  76. data/spec/lib/caracal/core/models/page_number_model_spec.rb +101 -0
  77. data/spec/lib/caracal/core/models/page_size_model_spec.rb +91 -0
  78. data/spec/lib/caracal/core/models/paragraph_model_spec.rb +162 -0
  79. data/spec/lib/caracal/core/models/relationship_model_spec.rb +183 -0
  80. data/spec/lib/caracal/core/models/rule_model_spec.rb +108 -0
  81. data/spec/lib/caracal/core/models/style_model_spec.rb +187 -0
  82. data/spec/lib/caracal/core/models/table_cell_model_spec.rb +221 -0
  83. data/spec/lib/caracal/core/models/table_model_spec.rb +222 -0
  84. data/spec/lib/caracal/core/models/text_model_spec.rb +132 -0
  85. data/spec/lib/caracal/core/page_breaks_spec.rb +25 -0
  86. data/spec/lib/caracal/core/page_numbers_spec.rb +80 -0
  87. data/spec/lib/caracal/core/page_settings_spec.rb +143 -0
  88. data/spec/lib/caracal/core/relationships_spec.rb +119 -0
  89. data/spec/lib/caracal/core/rules_spec.rb +25 -0
  90. data/spec/lib/caracal/core/styles_spec.rb +129 -0
  91. data/spec/lib/caracal/core/tables_spec.rb +25 -0
  92. data/spec/lib/caracal/core/text_spec.rb +52 -0
  93. data/spec/lib/caracal/errors_spec.rb +10 -0
  94. data/spec/spec_helper.rb +8 -0
  95. metadata +245 -0
@@ -0,0 +1,120 @@
1
+ require 'caracal/core/models/base_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+ module Models
7
+
8
+ # This class handles block options passed to the page margins
9
+ # method.
10
+ #
11
+ class BorderModel < BaseModel
12
+
13
+ #-------------------------------------------------------------
14
+ # Configuration
15
+ #-------------------------------------------------------------
16
+
17
+ # constants
18
+ const_set(:DEFAULT_BORDER_COLOR, 'auto')
19
+ const_set(:DEFAULT_BORDER_LINE, :single)
20
+ const_set(:DEFAULT_BORDER_SIZE, 4) # 0.5pt in 1/8 points
21
+ const_set(:DEFAULT_BORDER_SPACING, 1) # 0.125pt in 1/8 points
22
+ const_set(:DEFAULT_BORDER_TYPE, :top)
23
+
24
+ # accessors
25
+ attr_reader :border_color
26
+ attr_reader :border_line
27
+ attr_reader :border_size
28
+ attr_reader :border_spacing
29
+ attr_reader :border_type
30
+
31
+ # initialization
32
+ def initialize(**options, &block)
33
+ @border_color = DEFAULT_BORDER_COLOR
34
+ @border_line = DEFAULT_BORDER_LINE
35
+ @border_size = DEFAULT_BORDER_SIZE
36
+ @border_spacing = DEFAULT_BORDER_SPACING
37
+ @border_type = DEFAULT_BORDER_TYPE
38
+
39
+ super options, &block
40
+ end
41
+
42
+
43
+ #-------------------------------------------------------------
44
+ # Class Methods
45
+ #-------------------------------------------------------------
46
+
47
+ def self.formatted_type(type)
48
+ case type.to_s.to_sym
49
+ when :horizontal then 'insideH'
50
+ when :vertical then 'insideV'
51
+ when :top then 'top'
52
+ when :bottom then 'bottom'
53
+ when :left then 'left'
54
+ when :right then 'right'
55
+ else nil
56
+ end
57
+ end
58
+
59
+
60
+ #-------------------------------------------------------------
61
+ # Public Methods
62
+ #-------------------------------------------------------------
63
+
64
+ #=============== GETTERS ==============================
65
+
66
+ def formatted_type
67
+ self.class.formatted_type(border_type)
68
+ end
69
+
70
+ def total_size
71
+ border_size + (2 * border_spacing)
72
+ end
73
+
74
+
75
+ #=============== SETTERS ==============================
76
+
77
+ # integers
78
+ [:size, :spacing].each do |m|
79
+ define_method "#{ m }" do |value|
80
+ instance_variable_set("@border_#{ m }", value.to_i)
81
+ end
82
+ end
83
+
84
+ # strings
85
+ [:color].each do |m|
86
+ define_method "#{ m }" do |value|
87
+ instance_variable_set("@border_#{ m }", value.to_s)
88
+ end
89
+ end
90
+
91
+ # symbols
92
+ [:line, :type].each do |m|
93
+ define_method "#{ m }" do |value|
94
+ instance_variable_set("@border_#{ m }", value.to_s.to_sym)
95
+ end
96
+ end
97
+
98
+
99
+ #=============== VALIDATION ==============================
100
+
101
+ def valid?
102
+ dims = [border_size, border_spacing]
103
+ dims.all? { |d| d > 0 }
104
+ end
105
+
106
+
107
+ #-------------------------------------------------------------
108
+ # Private Instance Methods
109
+ #-------------------------------------------------------------
110
+ private
111
+
112
+ def option_keys
113
+ [:color, :line, :size, :spacing, :type]
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,64 @@
1
+ require 'caracal/core/models/base_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+ module Models
7
+
8
+ # This class encapsulates the logic needed to store and manipulate
9
+ # font data.
10
+ #
11
+ class FontModel < BaseModel
12
+
13
+ #-------------------------------------------------------------
14
+ # Configuration
15
+ #-------------------------------------------------------------
16
+
17
+ # accessors
18
+ attr_reader :font_name
19
+
20
+
21
+
22
+ #-------------------------------------------------------------
23
+ # Public Instance Methods
24
+ #-------------------------------------------------------------
25
+
26
+ #=============== SETTERS ==============================
27
+
28
+ # strings
29
+ [:name].each do |m|
30
+ define_method "#{ m }" do |value|
31
+ instance_variable_set("@font_#{ m }", value.to_s)
32
+ end
33
+ end
34
+
35
+
36
+ #=============== STATE ================================
37
+
38
+ def matches?(str)
39
+ font_name.to_s.downcase == str.to_s.downcase
40
+ end
41
+
42
+
43
+ #=============== VALIDATION ===========================
44
+
45
+ def valid?
46
+ a = [:name]
47
+ a.map { |m| send("font_#{ m }") }.compact.size == a.size
48
+ end
49
+
50
+
51
+ #-------------------------------------------------------------
52
+ # Private Instance Methods
53
+ #-------------------------------------------------------------
54
+ private
55
+
56
+ def option_keys
57
+ [:name]
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,118 @@
1
+ require 'caracal/core/models/base_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+ module Models
7
+
8
+ # This class handles block options passed to the img method.
9
+ #
10
+ class ImageModel < BaseModel
11
+
12
+ #-------------------------------------------------------------
13
+ # Configuration
14
+ #-------------------------------------------------------------
15
+
16
+ # constants
17
+ const_set(:DEFAULT_IMAGE_WIDTH, 0) # units in pixels. (will cause error)
18
+ const_set(:DEFAULT_IMAGE_HEIGHT, 0) # units in pixels. (will cause error)
19
+ const_set(:DEFAULT_IMAGE_ALIGN, :left)
20
+ const_set(:DEFAULT_IMAGE_TOP, 8) # units in pixels.
21
+ const_set(:DEFAULT_IMAGE_BOTTOM, 8) # units in pixels.
22
+ const_set(:DEFAULT_IMAGE_LEFT, 8) # units in pixels.
23
+ const_set(:DEFAULT_IMAGE_RIGHT, 8) # units in pixels.
24
+
25
+ # accessors
26
+ attr_reader :image_url
27
+ attr_reader :image_width
28
+ attr_reader :image_height
29
+ attr_reader :image_align
30
+ attr_reader :image_top
31
+ attr_reader :image_bottom
32
+ attr_reader :image_left
33
+ attr_reader :image_right
34
+
35
+
36
+ # initialization
37
+ def initialize(**options, &block)
38
+ @image_width = DEFAULT_IMAGE_WIDTH
39
+ @image_height = DEFAULT_IMAGE_HEIGHT
40
+ @image_align = DEFAULT_IMAGE_ALIGN
41
+ @image_top = DEFAULT_IMAGE_TOP
42
+ @image_bottom = DEFAULT_IMAGE_BOTTOM
43
+ @image_left = DEFAULT_IMAGE_LEFT
44
+ @image_right = DEFAULT_IMAGE_RIGHT
45
+
46
+ super options, &block
47
+ end
48
+
49
+
50
+ #-------------------------------------------------------------
51
+ # Public Methods
52
+ #-------------------------------------------------------------
53
+
54
+ #=============== GETTERS ==============================
55
+
56
+ [:width, :height, :top, :bottom, :left, :right].each do |m|
57
+ define_method "formatted_#{ m }" do
58
+ value = send("image_#{ m }")
59
+ pixels_to_emus(value)
60
+ end
61
+ end
62
+
63
+
64
+ #=============== SETTERS ==============================
65
+
66
+ # integers
67
+ [:width, :height, :top, :bottom, :left, :right].each do |m|
68
+ define_method "#{ m }" do |value|
69
+ instance_variable_set("@image_#{ m }", value.to_i)
70
+ end
71
+ end
72
+
73
+ # strings
74
+ [:url].each do |m|
75
+ define_method "#{ m }" do |value|
76
+ instance_variable_set("@image_#{ m }", value.to_s)
77
+ end
78
+ end
79
+
80
+ # symbols
81
+ [:align].each do |m|
82
+ define_method "#{ m }" do |value|
83
+ instance_variable_set("@image_#{ m }", value.to_s.to_sym)
84
+ end
85
+ end
86
+
87
+
88
+ #=============== VALIDATION ==============================
89
+
90
+ def valid?
91
+ dims = [:width, :height, :top, :bottom, :left, :right].map { |m| send("image_#{ m }") }
92
+ dims.all? { |d| d > 0 }
93
+ end
94
+
95
+
96
+
97
+ #-------------------------------------------------------------
98
+ # Private Methods
99
+ #-------------------------------------------------------------
100
+ private
101
+
102
+ def option_keys
103
+ [:url, :width, :height, :align, :top, :bottom, :left, :right]
104
+ end
105
+
106
+ def pixels_to_emus(value)
107
+ pixels = value.to_i
108
+ inches = pixels / 72.0
109
+ emus_per_inch = 914400
110
+
111
+ emus = (inches * emus_per_inch).to_i
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,15 @@
1
+ require 'caracal/core/models/base_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+ module Models
7
+
8
+ # This class encapsulates the logic needed to store and manipulate
9
+ # line break data.
10
+ #
11
+ class LineBreakModel < BaseModel; end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,65 @@
1
+ require 'caracal/core/models/text_model'
2
+
3
+
4
+ module Caracal
5
+ module Core
6
+ module Models
7
+
8
+ # This class encapsulates the logic needed to store and manipulate
9
+ # link data.
10
+ #
11
+ class LinkModel < TextModel
12
+
13
+ #-------------------------------------------------------------
14
+ # Configuration
15
+ #-------------------------------------------------------------
16
+
17
+ # readers (create aliases for superclass methods to conform
18
+ # to expected naming convention.)
19
+ attr_reader :link_href
20
+ alias_method :link_content, :text_content
21
+ alias_method :link_style, :text_style
22
+ alias_method :link_color, :text_color
23
+ alias_method :link_size, :text_size
24
+ alias_method :link_bold, :text_bold
25
+ alias_method :link_italic, :text_italic
26
+ alias_method :link_underline, :text_underline
27
+
28
+
29
+
30
+ #-------------------------------------------------------------
31
+ # Public Instance Methods
32
+ #-------------------------------------------------------------
33
+
34
+ #=============== SETTERS ==============================
35
+
36
+ # strings
37
+ [:href].each do |m|
38
+ define_method "#{ m }" do |value|
39
+ instance_variable_set("@link_#{ m }", value.to_s)
40
+ end
41
+ end
42
+
43
+
44
+ #=============== VALIDATION ===========================
45
+
46
+ def valid?
47
+ a = [:content, :href]
48
+ a.map { |m| send("link_#{ m }") }.compact.size == a.size
49
+ end
50
+
51
+
52
+ #-------------------------------------------------------------
53
+ # Private Instance Methods
54
+ #-------------------------------------------------------------
55
+ private
56
+
57
+ def option_keys
58
+ (super + [:href]).flatten
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,105 @@
1
+ require 'caracal/core/models/list_model'
2
+ require 'caracal/core/models/paragraph_model'
3
+ require 'caracal/errors'
4
+
5
+
6
+ module Caracal
7
+ module Core
8
+ module Models
9
+
10
+ # This class encapsulates the logic needed to store and manipulate
11
+ # list item data.
12
+ #
13
+ class ListItemModel < ParagraphModel
14
+
15
+ #-------------------------------------------------------------
16
+ # Configuration
17
+ #-------------------------------------------------------------
18
+
19
+ # accessors
20
+ attr_accessor :nested_list
21
+
22
+ # readers (create aliases for superclass methods to conform
23
+ # to expected naming convention.)
24
+ attr_reader :list_item_type
25
+ attr_reader :list_item_level
26
+ alias_method :list_item_style, :paragraph_style
27
+ alias_method :list_item_color, :paragraph_color
28
+ alias_method :list_item_size, :paragraph_size
29
+ alias_method :list_item_bold, :paragraph_bold
30
+ alias_method :list_item_italic, :paragraph_italic
31
+ alias_method :list_item_underline, :paragraph_underline
32
+
33
+
34
+
35
+ #-------------------------------------------------------------
36
+ # Public Instance Methods
37
+ #-------------------------------------------------------------
38
+
39
+ #=============== SETTERS ==============================
40
+
41
+ # integers
42
+ [:level].each do |m|
43
+ define_method "#{ m }" do |value|
44
+ instance_variable_set("@list_item_#{ m }", value.to_i)
45
+ end
46
+ end
47
+
48
+ # symbols
49
+ [:type].each do |m|
50
+ define_method "#{ m }" do |value|
51
+ instance_variable_set("@list_item_#{ m }", value.to_s.to_sym)
52
+ end
53
+ end
54
+
55
+
56
+ #=============== SUB-METHODS ===========================
57
+
58
+ # .ol
59
+ def ol(**options, &block)
60
+ options.merge!({ type: :ordered, level: list_item_level + 1 })
61
+
62
+ model = Caracal::Core::Models::ListModel.new(options, &block)
63
+ if model.valid?
64
+ @nested_list = model
65
+ else
66
+ raise Caracal::Errors::InvalidModelError, 'Ordered lists require at least one list item.'
67
+ end
68
+ end
69
+
70
+ # .ul
71
+ def ul(**options, &block)
72
+ options.merge!({ type: :unordered, level: list_item_level + 1 })
73
+
74
+ model = Caracal::Core::Models::ListModel.new(options, &block)
75
+ if model.valid?
76
+ @nested_list = model
77
+ else
78
+ raise Caracal::Errors::InvalidModelError, 'Unordered lists require at least one list item.'
79
+ end
80
+ end
81
+
82
+
83
+ #=============== VALIDATION ===========================
84
+
85
+ def valid?
86
+ a = [:type, :level]
87
+ required = a.map { |m| send("list_item_#{ m }") }.compact.size == a.size
88
+ required && !runs.empty?
89
+ end
90
+
91
+
92
+ #-------------------------------------------------------------
93
+ # Private Instance Methods
94
+ #-------------------------------------------------------------
95
+ private
96
+
97
+ def option_keys
98
+ [:type, :level, :content, :style, :color, :size, :bold, :italic, :underline]
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+ end
105
+ end