squib 0.0.3 → 0.0.4
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 +4 -4
- data/.gitignore +29 -29
- data/.travis.yml +6 -6
- data/.yardopts +7 -7
- data/CHANGELOG.md +19 -0
- data/Gemfile +2 -2
- data/LICENSE.txt +22 -22
- data/README.md +256 -244
- data/Rakefile +11 -11
- data/bin/squib +18 -18
- data/lib/squib.rb +31 -31
- data/lib/squib/api/background.rb +18 -18
- data/lib/squib/api/data.rb +52 -52
- data/lib/squib/api/image.rb +66 -66
- data/lib/squib/api/save.rb +43 -43
- data/lib/squib/api/settings.rb +37 -38
- data/lib/squib/api/shapes.rb +116 -116
- data/lib/squib/api/text.rb +53 -50
- data/lib/squib/api/units.rb +16 -16
- data/lib/squib/card.rb +41 -41
- data/lib/squib/commands/new.rb +43 -43
- data/lib/squib/constants.rb +108 -104
- data/lib/squib/deck.rb +170 -116
- data/lib/squib/graphics/background.rb +13 -13
- data/lib/squib/graphics/image.rb +47 -47
- data/lib/squib/graphics/save_doc.rb +54 -54
- data/lib/squib/graphics/save_images.rb +32 -32
- data/lib/squib/graphics/shapes.rb +59 -59
- data/lib/squib/graphics/text.rb +116 -113
- data/lib/squib/input_helpers.rb +193 -193
- data/lib/squib/progress.rb +37 -37
- data/lib/squib/project_template/.gitignore +4 -4
- data/lib/squib/project_template/ABOUT.md +19 -19
- data/lib/squib/project_template/Gemfile +2 -2
- data/lib/squib/project_template/PNP NOTES.md +3 -3
- data/lib/squib/project_template/config.yml +19 -19
- data/lib/squib/project_template/deck.rb +5 -5
- data/lib/squib/version.rb +6 -6
- data/samples/autoscale_font.rb +27 -0
- data/samples/basic.rb +19 -19
- data/samples/colors.rb +15 -15
- data/samples/custom-config.yml +5 -5
- data/samples/custom-layout.yml +59 -39
- data/samples/custom_config.rb +18 -18
- data/samples/customconfig-imgdir/spanner2.svg +91 -91
- data/samples/draw_shapes.rb +18 -18
- data/samples/excel.rb +19 -19
- data/samples/hello_world.rb +6 -6
- data/samples/load_images.rb +29 -29
- data/samples/offset.svg +71 -71
- data/samples/portrait-landscape.rb +22 -22
- data/samples/ranges.rb +55 -55
- data/samples/save_pdf.rb +14 -14
- data/samples/spanner.svg +91 -91
- data/samples/text_options.rb +67 -60
- data/samples/tgc_proofs.rb +19 -19
- data/samples/units.rb +12 -12
- data/samples/use_layout.rb +33 -28
- data/spec/api/api_text_spec.rb +43 -43
- data/spec/commands/new_spec.rb +47 -47
- data/spec/data/easy-circular-extends.yml +6 -0
- data/spec/data/hard-circular-extends.yml +9 -0
- data/spec/data/multi-extends-single-entry.yml +14 -13
- data/spec/data/multi-level-extends.yml +9 -9
- data/spec/data/no-extends.yml +5 -5
- data/spec/data/pre-extends.yml +7 -0
- data/spec/data/self-circular-extends.yml +3 -0
- data/spec/data/single-extends.yml +7 -7
- data/spec/data/single-level-multi-extends.yml +11 -11
- data/spec/deck_spec.rb +188 -147
- data/spec/input_helpers_spec.rb +116 -116
- data/spec/samples_run_spec.rb +19 -19
- data/squib.gemspec +46 -46
- metadata +17 -7
data/lib/squib/commands/new.rb
CHANGED
@@ -1,44 +1,44 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
module Squib
|
4
|
-
# Squib's command-line options
|
5
|
-
module Commands
|
6
|
-
|
7
|
-
# Generate a new Squib project into a fresh directory.
|
8
|
-
#
|
9
|
-
# Provides conventions for using Git (you are using version control, right??).
|
10
|
-
# Also provides some basic layout and config files to start from, along with templates for instructions and other notes you don't want to forget.
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# squib new foo-blasters
|
15
|
-
# cd foo-blasters
|
16
|
-
# ruby deck.rb
|
17
|
-
# git init
|
18
|
-
# git add .
|
19
|
-
# git commit -m "Starting my cool new game using Squib!"
|
20
|
-
#
|
21
|
-
# @api public
|
22
|
-
class New
|
23
|
-
|
24
|
-
# :nodoc:
|
25
|
-
# @api private
|
26
|
-
def process(args)
|
27
|
-
raise ArgumentError.new('Please specify a path.') if args.empty?
|
28
|
-
|
29
|
-
new_project_path = File.expand_path(args.join(" "), Dir.pwd)
|
30
|
-
template_path = File.expand_path('../project_template', File.dirname(__FILE__))
|
31
|
-
|
32
|
-
FileUtils.mkdir_p new_project_path
|
33
|
-
if !Dir["#{new_project_path}/**/*"].empty?
|
34
|
-
$stderr.puts "#{new_project_path} exists and is not empty. Doing nothing and quitting."
|
35
|
-
else
|
36
|
-
Dir.chdir(new_project_path) do
|
37
|
-
FileUtils.cp_r template_path + '/.', new_project_path
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Squib
|
4
|
+
# Squib's command-line options
|
5
|
+
module Commands
|
6
|
+
|
7
|
+
# Generate a new Squib project into a fresh directory.
|
8
|
+
#
|
9
|
+
# Provides conventions for using Git (you are using version control, right??).
|
10
|
+
# Also provides some basic layout and config files to start from, along with templates for instructions and other notes you don't want to forget.
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# squib new foo-blasters
|
15
|
+
# cd foo-blasters
|
16
|
+
# ruby deck.rb
|
17
|
+
# git init
|
18
|
+
# git add .
|
19
|
+
# git commit -m "Starting my cool new game using Squib!"
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
class New
|
23
|
+
|
24
|
+
# :nodoc:
|
25
|
+
# @api private
|
26
|
+
def process(args)
|
27
|
+
raise ArgumentError.new('Please specify a path.') if args.empty?
|
28
|
+
|
29
|
+
new_project_path = File.expand_path(args.join(" "), Dir.pwd)
|
30
|
+
template_path = File.expand_path('../project_template', File.dirname(__FILE__))
|
31
|
+
|
32
|
+
FileUtils.mkdir_p new_project_path
|
33
|
+
if !Dir["#{new_project_path}/**/*"].empty?
|
34
|
+
$stderr.puts "#{new_project_path} exists and is not empty. Doing nothing and quitting."
|
35
|
+
else
|
36
|
+
Dir.chdir(new_project_path) do
|
37
|
+
FileUtils.cp_r template_path + '/.', new_project_path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
44
|
end
|
data/lib/squib/constants.rb
CHANGED
@@ -1,105 +1,109 @@
|
|
1
|
-
module Squib
|
2
|
-
# Squib's defaults for when arguments are not specified in the command nor layouts.
|
3
|
-
#
|
4
|
-
# @api public
|
5
|
-
SYSTEM_DEFAULTS = {
|
6
|
-
:align => :left,
|
7
|
-
:alpha => 1.0,
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
88
|
-
:
|
89
|
-
:
|
90
|
-
:
|
91
|
-
:
|
92
|
-
:
|
93
|
-
:
|
94
|
-
:
|
95
|
-
:
|
96
|
-
:
|
97
|
-
:
|
98
|
-
:
|
99
|
-
:
|
100
|
-
:
|
101
|
-
:
|
102
|
-
:
|
103
|
-
:
|
104
|
-
|
1
|
+
module Squib
|
2
|
+
# Squib's defaults for when arguments are not specified in the command nor layouts.
|
3
|
+
#
|
4
|
+
# @api public
|
5
|
+
SYSTEM_DEFAULTS = {
|
6
|
+
:align => :left,
|
7
|
+
:alpha => 1.0,
|
8
|
+
:angle => 0,
|
9
|
+
:blend => :none,
|
10
|
+
:color => :black,
|
11
|
+
:default_font => 'Arial 36',
|
12
|
+
:dir => "_output",
|
13
|
+
:ellipsize => :end,
|
14
|
+
:fill_color => '#0000',
|
15
|
+
:force_id => false,
|
16
|
+
:font => :use_set,
|
17
|
+
:font_size => nil,
|
18
|
+
:format => :png,
|
19
|
+
:gap => 0,
|
20
|
+
:height => :native,
|
21
|
+
:hint => :off,
|
22
|
+
:img_dir => '.',
|
23
|
+
:justify => false,
|
24
|
+
:margin => 75,
|
25
|
+
:markup => false,
|
26
|
+
:prefix => "card_",
|
27
|
+
:progress_bar => false,
|
28
|
+
:range => :all,
|
29
|
+
:rotate => false,
|
30
|
+
:sheet => 0,
|
31
|
+
:spacing => 0,
|
32
|
+
:str => '',
|
33
|
+
:stroke_color => :black,
|
34
|
+
:stroke_width => 2.0,
|
35
|
+
:trim => 0,
|
36
|
+
:valign => :top,
|
37
|
+
:width => :native,
|
38
|
+
:wrap => true,
|
39
|
+
:x => 0,
|
40
|
+
:x1 => 100,
|
41
|
+
:x2 => 150,
|
42
|
+
:x3 => 100,
|
43
|
+
:x_radius => 0,
|
44
|
+
:y => 0,
|
45
|
+
:y1 => 100,
|
46
|
+
:y2 => 150,
|
47
|
+
:y3 => 150,
|
48
|
+
:y_radius => 0,
|
49
|
+
}
|
50
|
+
|
51
|
+
# Squib's configuration defaults
|
52
|
+
#
|
53
|
+
# @api public
|
54
|
+
CONFIG_DEFAULTS = {
|
55
|
+
'custom_colors' => {},
|
56
|
+
'dpi' => 300,
|
57
|
+
'hint' => :none,
|
58
|
+
'progress_bar' => false,
|
59
|
+
'img_dir' => '.',
|
60
|
+
}
|
61
|
+
|
62
|
+
# These are parameters that are intended to be "expanded" across
|
63
|
+
# range if they are singletons.
|
64
|
+
#
|
65
|
+
# For example, using a different font for each card, using one `text`
|
66
|
+
#
|
67
|
+
# key: the internal name of the param (e.g. :files)
|
68
|
+
# value: the user-facing API key (e.g. file: 'abc.png')
|
69
|
+
#
|
70
|
+
# @api private
|
71
|
+
EXPANDING_PARAMS = {
|
72
|
+
:align => :align,
|
73
|
+
:alpha => :alpha,
|
74
|
+
:angle => :angle,
|
75
|
+
:blend => :blend,
|
76
|
+
:circle_radius => :radius,
|
77
|
+
:color => :color,
|
78
|
+
:ellipsize => :ellipsize,
|
79
|
+
:files => :file,
|
80
|
+
:fill_color => :fill_color,
|
81
|
+
:force_svgid => :force_id,
|
82
|
+
:font => :font,
|
83
|
+
:font_size => :font_size,
|
84
|
+
:height => :height,
|
85
|
+
:hint => :hint,
|
86
|
+
:justify => :justify,
|
87
|
+
:layout => :layout,
|
88
|
+
:markup => :markup,
|
89
|
+
:rect_radius => :radius,
|
90
|
+
:spacing => :spacing,
|
91
|
+
:str => :str,
|
92
|
+
:stroke_color => :stroke_color,
|
93
|
+
:stroke_width => :stroke_width,
|
94
|
+
:svgid => :id,
|
95
|
+
:valign => :valign,
|
96
|
+
:width => :width,
|
97
|
+
:wrap => :wrap,
|
98
|
+
:x => :x,
|
99
|
+
:x1 => :x1,
|
100
|
+
:x2 => :x2,
|
101
|
+
:x3 => :x3,
|
102
|
+
:x_radius => :x_radius,
|
103
|
+
:y => :y,
|
104
|
+
:y1 => :y1,
|
105
|
+
:y2 => :y2,
|
106
|
+
:y3 => :y3,
|
107
|
+
:y_radius => :y_radius,
|
108
|
+
}
|
105
109
|
end
|
data/lib/squib/deck.rb
CHANGED
@@ -1,117 +1,171 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'pp'
|
3
|
-
require 'squib'
|
4
|
-
require 'squib/card'
|
5
|
-
require 'squib/progress'
|
6
|
-
require 'squib/input_helpers'
|
7
|
-
require 'squib/constants'
|
8
|
-
|
9
|
-
# The project module
|
10
|
-
#
|
11
|
-
# @api public
|
12
|
-
module Squib
|
13
|
-
|
14
|
-
# The main interface to Squib. Provides a front-end porcelain whereas the Card class interacts with the graphics plumbing.
|
15
|
-
#
|
16
|
-
# @api public
|
17
|
-
class Deck
|
18
|
-
include Enumerable
|
19
|
-
include Squib::InputHelpers
|
20
|
-
|
21
|
-
# :nodoc:
|
22
|
-
# @api private
|
23
|
-
attr_reader :width, :height
|
24
|
-
|
25
|
-
# :nodoc:
|
26
|
-
# @api private
|
27
|
-
attr_reader :cards
|
28
|
-
|
29
|
-
# :nodoc:
|
30
|
-
# @api private
|
31
|
-
attr_reader :text_hint
|
32
|
-
|
33
|
-
# :nodoc:
|
34
|
-
# @api private
|
35
|
-
attr_reader :layout, :config
|
36
|
-
|
37
|
-
# Squib's constructor that sets the immutable properties.
|
38
|
-
#
|
39
|
-
# This is the starting point for Squib. In providing a block to the constructor, you have access to all of Deck's instance methods.
|
40
|
-
# The documented methods in Deck are the ones intended for use by most users.
|
41
|
-
# If your game requires multiple different sizes or orientations, I recommend using multiple `Squib::Deck`s in your `deck.rb`. You can modify the internals of `Squib::Deck` (e.g. `@cards`), but that's not recommended.
|
42
|
-
# @example
|
43
|
-
# require 'squib'
|
44
|
-
# Squib::Deck.new do
|
45
|
-
# text str: 'Hello, World!'
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# @param width: [Integer] the width of each card in pixels
|
49
|
-
# @param height: [Integer] the height of each card in pixels
|
50
|
-
# @param cards: [Integer] the number of cards in the deck
|
51
|
-
# @param dpi: [Integer] the pixels per inch when rendering out to PDF or calculating using inches.
|
52
|
-
# @param config: [String] the
|
53
|
-
# @param
|
54
|
-
# @
|
55
|
-
|
56
|
-
|
57
|
-
@
|
58
|
-
@
|
59
|
-
@
|
60
|
-
@
|
61
|
-
@
|
62
|
-
@
|
63
|
-
@
|
64
|
-
cards.times{ @cards << Squib::Card.new(self, width, height) }
|
65
|
-
load_config(config)
|
66
|
-
|
67
|
-
if block_given?
|
68
|
-
instance_eval(&block)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Directly accesses the array of cards in the deck
|
73
|
-
#
|
74
|
-
# @api private
|
75
|
-
def [](key)
|
76
|
-
@cards[key]
|
77
|
-
end
|
78
|
-
|
79
|
-
# Iterates over each card in the deck
|
80
|
-
#
|
81
|
-
# @api private
|
82
|
-
def each(&block)
|
83
|
-
@cards.each { |card| block.call(card) }
|
84
|
-
end
|
85
|
-
|
86
|
-
# Shows a descriptive place of the location
|
87
|
-
def location(opts)
|
88
|
-
opts[:layout] || (" @ #{opts[:x]},#{opts[:y]}")
|
89
|
-
end
|
90
|
-
|
91
|
-
# Load the configuration file, if exists, overriding hardcoded defaults
|
92
|
-
# @api private
|
93
|
-
def load_config(file)
|
94
|
-
if File.exists?(file) && config = YAML.load_file(file)
|
95
|
-
config = Squib::CONFIG_DEFAULTS.merge(config)
|
96
|
-
@dpi = config['dpi'].to_i
|
97
|
-
@text_hint = config['text_hint']
|
98
|
-
@progress_bar.enabled = config['progress_bars']
|
99
|
-
@custom_colors = config['custom_colors']
|
100
|
-
@img_dir = config['img_dir']
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
1
|
+
require 'yaml'
|
2
|
+
require 'pp'
|
3
|
+
require 'squib'
|
4
|
+
require 'squib/card'
|
5
|
+
require 'squib/progress'
|
6
|
+
require 'squib/input_helpers'
|
7
|
+
require 'squib/constants'
|
8
|
+
|
9
|
+
# The project module
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
module Squib
|
13
|
+
|
14
|
+
# The main interface to Squib. Provides a front-end porcelain whereas the Card class interacts with the graphics plumbing.
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
class Deck
|
18
|
+
include Enumerable
|
19
|
+
include Squib::InputHelpers
|
20
|
+
|
21
|
+
# :nodoc:
|
22
|
+
# @api private
|
23
|
+
attr_reader :width, :height
|
24
|
+
|
25
|
+
# :nodoc:
|
26
|
+
# @api private
|
27
|
+
attr_reader :cards
|
28
|
+
|
29
|
+
# :nodoc:
|
30
|
+
# @api private
|
31
|
+
attr_reader :text_hint
|
32
|
+
|
33
|
+
# :nodoc:
|
34
|
+
# @api private
|
35
|
+
attr_reader :layout, :config
|
36
|
+
|
37
|
+
# Squib's constructor that sets the immutable properties.
|
38
|
+
#
|
39
|
+
# This is the starting point for Squib. In providing a block to the constructor, you have access to all of Deck's instance methods.
|
40
|
+
# The documented methods in Deck are the ones intended for use by most users.
|
41
|
+
# If your game requires multiple different sizes or orientations, I recommend using multiple `Squib::Deck`s in your `deck.rb`. You can modify the internals of `Squib::Deck` (e.g. `@cards`), but that's not recommended.
|
42
|
+
# @example
|
43
|
+
# require 'squib'
|
44
|
+
# Squib::Deck.new do
|
45
|
+
# text str: 'Hello, World!'
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @param width: [Integer] the width of each card in pixels
|
49
|
+
# @param height: [Integer] the height of each card in pixels
|
50
|
+
# @param cards: [Integer] the number of cards in the deck
|
51
|
+
# @param dpi: [Integer] the pixels per inch when rendering out to PDF or calculating using inches.
|
52
|
+
# @param config: [String] the file used for global settings of this deck
|
53
|
+
# @param block [Block] the main body of the script.
|
54
|
+
# @api public
|
55
|
+
def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block)
|
56
|
+
@width=width; @height=height
|
57
|
+
@dpi = dpi
|
58
|
+
@font = Squib::SYSTEM_DEFAULTS[:default_font]
|
59
|
+
@cards = []
|
60
|
+
@custom_colors = {}
|
61
|
+
@img_dir = '.'
|
62
|
+
@progress_bar = Squib::Progress.new(false)
|
63
|
+
@text_hint = :off
|
64
|
+
cards.times{ @cards << Squib::Card.new(self, width, height) }
|
65
|
+
load_config(config)
|
66
|
+
load_layout(layout)
|
67
|
+
if block_given?
|
68
|
+
instance_eval(&block)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Directly accesses the array of cards in the deck
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
def [](key)
|
76
|
+
@cards[key]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Iterates over each card in the deck
|
80
|
+
#
|
81
|
+
# @api private
|
82
|
+
def each(&block)
|
83
|
+
@cards.each { |card| block.call(card) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Shows a descriptive place of the location
|
87
|
+
def location(opts)
|
88
|
+
opts[:layout] || (" @ #{opts[:x]},#{opts[:y]}")
|
89
|
+
end
|
90
|
+
|
91
|
+
# Load the configuration file, if exists, overriding hardcoded defaults
|
92
|
+
# @api private
|
93
|
+
def load_config(file)
|
94
|
+
if File.exists?(file) && config = YAML.load_file(file)
|
95
|
+
config = Squib::CONFIG_DEFAULTS.merge(config)
|
96
|
+
@dpi = config['dpi'].to_i
|
97
|
+
@text_hint = config['text_hint']
|
98
|
+
@progress_bar.enabled = config['progress_bars']
|
99
|
+
@custom_colors = config['custom_colors']
|
100
|
+
@img_dir = config['img_dir']
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Load the layout configuration file, if exists
|
105
|
+
# @api private
|
106
|
+
def load_layout(file)
|
107
|
+
return if file.nil?
|
108
|
+
@layout = {}
|
109
|
+
yml = YAML.load_file(file)
|
110
|
+
yml.each do |key, value|
|
111
|
+
@layout[key] = recurse_extends(yml, key, {})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Process the extends recursively
|
116
|
+
# :nodoc:
|
117
|
+
# @api private
|
118
|
+
def recurse_extends(yml, key, visited )
|
119
|
+
assert_not_visited(key, visited)
|
120
|
+
return yml[key] unless has_extends?(yml, key)
|
121
|
+
visited[key] = key
|
122
|
+
parent_keys = [yml[key]['extends']].flatten
|
123
|
+
h = {}
|
124
|
+
parent_keys.each do |parent_key|
|
125
|
+
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
|
126
|
+
if child_val.to_s.strip.start_with?('+=')
|
127
|
+
parent_val + child_val.sub("+=",'').strip.to_f
|
128
|
+
elsif child_val.to_s.strip.start_with?('-=')
|
129
|
+
parent_val - child_val.sub("-=",'').strip.to_f
|
130
|
+
else
|
131
|
+
child_val #child overrides parent when merging, no +=
|
132
|
+
end
|
133
|
+
end
|
134
|
+
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
|
135
|
+
younger_sibling #when two siblings have the same entry, the "younger" (lower one) overrides
|
136
|
+
end
|
137
|
+
end
|
138
|
+
return h
|
139
|
+
end
|
140
|
+
|
141
|
+
# Does this layout entry have an extends field?
|
142
|
+
# i.e. is it a base-case or will it need recursion?
|
143
|
+
# :nodoc:
|
144
|
+
# @api private
|
145
|
+
def has_extends?(yml, key)
|
146
|
+
yml[key].key?('extends')
|
147
|
+
end
|
148
|
+
|
149
|
+
# Safeguard against malformed circular extends
|
150
|
+
# :nodoc:
|
151
|
+
# @api private
|
152
|
+
def assert_not_visited(key, visited)
|
153
|
+
if visited.key? key
|
154
|
+
raise "Invalid layout: circular extends with '#{key}'"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
##################
|
159
|
+
### PUBLIC API ###
|
160
|
+
##################
|
161
|
+
require 'squib/api/background'
|
162
|
+
require 'squib/api/data'
|
163
|
+
require 'squib/api/image'
|
164
|
+
require 'squib/api/save'
|
165
|
+
require 'squib/api/settings'
|
166
|
+
require 'squib/api/shapes'
|
167
|
+
require 'squib/api/text'
|
168
|
+
require 'squib/api/units'
|
169
|
+
|
170
|
+
end
|
117
171
|
end
|