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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +29 -29
  3. data/.travis.yml +6 -6
  4. data/.yardopts +7 -7
  5. data/CHANGELOG.md +19 -0
  6. data/Gemfile +2 -2
  7. data/LICENSE.txt +22 -22
  8. data/README.md +256 -244
  9. data/Rakefile +11 -11
  10. data/bin/squib +18 -18
  11. data/lib/squib.rb +31 -31
  12. data/lib/squib/api/background.rb +18 -18
  13. data/lib/squib/api/data.rb +52 -52
  14. data/lib/squib/api/image.rb +66 -66
  15. data/lib/squib/api/save.rb +43 -43
  16. data/lib/squib/api/settings.rb +37 -38
  17. data/lib/squib/api/shapes.rb +116 -116
  18. data/lib/squib/api/text.rb +53 -50
  19. data/lib/squib/api/units.rb +16 -16
  20. data/lib/squib/card.rb +41 -41
  21. data/lib/squib/commands/new.rb +43 -43
  22. data/lib/squib/constants.rb +108 -104
  23. data/lib/squib/deck.rb +170 -116
  24. data/lib/squib/graphics/background.rb +13 -13
  25. data/lib/squib/graphics/image.rb +47 -47
  26. data/lib/squib/graphics/save_doc.rb +54 -54
  27. data/lib/squib/graphics/save_images.rb +32 -32
  28. data/lib/squib/graphics/shapes.rb +59 -59
  29. data/lib/squib/graphics/text.rb +116 -113
  30. data/lib/squib/input_helpers.rb +193 -193
  31. data/lib/squib/progress.rb +37 -37
  32. data/lib/squib/project_template/.gitignore +4 -4
  33. data/lib/squib/project_template/ABOUT.md +19 -19
  34. data/lib/squib/project_template/Gemfile +2 -2
  35. data/lib/squib/project_template/PNP NOTES.md +3 -3
  36. data/lib/squib/project_template/config.yml +19 -19
  37. data/lib/squib/project_template/deck.rb +5 -5
  38. data/lib/squib/version.rb +6 -6
  39. data/samples/autoscale_font.rb +27 -0
  40. data/samples/basic.rb +19 -19
  41. data/samples/colors.rb +15 -15
  42. data/samples/custom-config.yml +5 -5
  43. data/samples/custom-layout.yml +59 -39
  44. data/samples/custom_config.rb +18 -18
  45. data/samples/customconfig-imgdir/spanner2.svg +91 -91
  46. data/samples/draw_shapes.rb +18 -18
  47. data/samples/excel.rb +19 -19
  48. data/samples/hello_world.rb +6 -6
  49. data/samples/load_images.rb +29 -29
  50. data/samples/offset.svg +71 -71
  51. data/samples/portrait-landscape.rb +22 -22
  52. data/samples/ranges.rb +55 -55
  53. data/samples/save_pdf.rb +14 -14
  54. data/samples/spanner.svg +91 -91
  55. data/samples/text_options.rb +67 -60
  56. data/samples/tgc_proofs.rb +19 -19
  57. data/samples/units.rb +12 -12
  58. data/samples/use_layout.rb +33 -28
  59. data/spec/api/api_text_spec.rb +43 -43
  60. data/spec/commands/new_spec.rb +47 -47
  61. data/spec/data/easy-circular-extends.yml +6 -0
  62. data/spec/data/hard-circular-extends.yml +9 -0
  63. data/spec/data/multi-extends-single-entry.yml +14 -13
  64. data/spec/data/multi-level-extends.yml +9 -9
  65. data/spec/data/no-extends.yml +5 -5
  66. data/spec/data/pre-extends.yml +7 -0
  67. data/spec/data/self-circular-extends.yml +3 -0
  68. data/spec/data/single-extends.yml +7 -7
  69. data/spec/data/single-level-multi-extends.yml +11 -11
  70. data/spec/deck_spec.rb +188 -147
  71. data/spec/input_helpers_spec.rb +116 -116
  72. data/spec/samples_run_spec.rb +19 -19
  73. data/squib.gemspec +46 -46
  74. metadata +17 -7
@@ -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
@@ -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
- :blend => :none,
9
- :color => :black,
10
- :default_font => 'Arial 36',
11
- :dir => "_output",
12
- :ellipsize => :end,
13
- :fill_color => '#0000',
14
- :force_id => false,
15
- :font => :use_set,
16
- :format => :png,
17
- :gap => 0,
18
- :height => :native,
19
- :hint => :off,
20
- :img_dir => '.',
21
- :justify => false,
22
- :margin => 75,
23
- :markup => false,
24
- :prefix => "card_",
25
- :progress_bar => false,
26
- :range => :all,
27
- :rotate => false,
28
- :sheet => 0,
29
- :spacing => 0,
30
- :str => '',
31
- :stroke_color => :black,
32
- :stroke_width => 2.0,
33
- :trim => 0,
34
- :valign => :top,
35
- :width => :native,
36
- :wrap => true,
37
- :x => 0,
38
- :x1 => 100,
39
- :x2 => 150,
40
- :x3 => 100,
41
- :x_radius => 0,
42
- :y => 0,
43
- :y1 => 100,
44
- :y2 => 150,
45
- :y3 => 150,
46
- :y_radius => 0,
47
- }
48
-
49
- # Squib's configuration defaults
50
- #
51
- # @api public
52
- CONFIG_DEFAULTS = {
53
- 'custom_colors' => {},
54
- 'dpi' => 300,
55
- 'hint' => :none,
56
- 'progress_bar' => false,
57
- 'img_dir' => '.',
58
- }
59
-
60
- # These are parameters that are intended to be "expanded" across
61
- # range if they are singletons.
62
- #
63
- # For example, using a different font for each card, using one `text`
64
- #
65
- # key: the internal name of the param (e.g. :files)
66
- # value: the user-facing API key (e.g. file: 'abc.png')
67
- #
68
- # @api private
69
- EXPANDING_PARAMS = {
70
- :align => :align,
71
- :alpha => :alpha,
72
- :blend => :blend,
73
- :circle_radius => :radius,
74
- :color => :color,
75
- :ellipsize => :ellipsize,
76
- :files => :file,
77
- :fill_color => :fill_color,
78
- :force_svgid => :force_id,
79
- :font => :font,
80
- :height => :height,
81
- :hint => :hint,
82
- :justify => :justify,
83
- :layout => :layout,
84
- :markup => :markup,
85
- :rect_radius => :radius,
86
- :spacing => :spacing,
87
- :str => :str,
88
- :stroke_color => :stroke_color,
89
- :stroke_width => :stroke_width,
90
- :svgid => :id,
91
- :valign => :valign,
92
- :width => :width,
93
- :wrap => :wrap,
94
- :x => :x,
95
- :x1 => :x1,
96
- :x2 => :x2,
97
- :x3 => :x3,
98
- :x_radius => :x_radius,
99
- :y => :y,
100
- :y1 => :y1,
101
- :y2 => :y2,
102
- :y2 => :y3,
103
- :y_radius => :y_radius,
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
@@ -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 Yaml file used for global settings of this deck
53
- # @param layout: [String] the Yaml file used for layouts.
54
- # @param block [Block] the main body of the script.
55
- # @api public
56
- def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block)
57
- @width=width; @height=height
58
- @dpi = dpi
59
- @font = Squib::SYSTEM_DEFAULTS[:default_font]
60
- @cards = []
61
- @custom_colors = {}
62
- @img_dir = '.'
63
- @progress_bar = Squib::Progress.new(false)
64
- cards.times{ @cards << Squib::Card.new(self, width, height) }
65
- load_config(config)
66
- @layout = YAML.load_file(layout) unless layout.nil?
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
- ### PUBLIC API ###
106
- ##################
107
- require 'squib/api/background'
108
- require 'squib/api/data'
109
- require 'squib/api/image'
110
- require 'squib/api/save'
111
- require 'squib/api/settings'
112
- require 'squib/api/shapes'
113
- require 'squib/api/text'
114
- require 'squib/api/units'
115
-
116
- end
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