squib 0.0.4 → 0.0.5

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +38 -33
  5. data/Rakefile +1 -1
  6. data/bin/squib +6 -6
  7. data/lib/squib.rb +8 -8
  8. data/lib/squib/api/background.rb +3 -3
  9. data/lib/squib/api/data.rb +5 -6
  10. data/lib/squib/api/image.rb +13 -10
  11. data/lib/squib/api/save.rb +4 -5
  12. data/lib/squib/api/settings.rb +4 -4
  13. data/lib/squib/api/shapes.rb +20 -20
  14. data/lib/squib/api/text.rb +11 -11
  15. data/lib/squib/api/units.rb +4 -4
  16. data/lib/squib/card.rb +5 -5
  17. data/lib/squib/commands/new.rb +5 -5
  18. data/lib/squib/constants.rb +10 -10
  19. data/lib/squib/deck.rb +24 -22
  20. data/lib/squib/graphics/background.rb +3 -3
  21. data/lib/squib/graphics/image.rb +13 -6
  22. data/lib/squib/graphics/save_doc.rb +13 -11
  23. data/lib/squib/graphics/save_images.rb +3 -3
  24. data/lib/squib/graphics/shapes.rb +9 -8
  25. data/lib/squib/graphics/text.rb +61 -59
  26. data/lib/squib/input_helpers.rb +13 -13
  27. data/lib/squib/progress.rb +4 -4
  28. data/lib/squib/project_template/Gemfile +1 -1
  29. data/lib/squib/project_template/deck.rb +3 -3
  30. data/lib/squib/version.rb +6 -2
  31. data/samples/autoscale_font.rb +4 -4
  32. data/samples/basic.rb +6 -7
  33. data/samples/cairo_access.rb +27 -0
  34. data/samples/colors.rb +2 -2
  35. data/samples/custom-layout.yml +5 -5
  36. data/samples/custom_config.rb +4 -4
  37. data/samples/draw_shapes.rb +8 -8
  38. data/samples/hello_world.rb +2 -3
  39. data/samples/load_images.rb +6 -1
  40. data/samples/portrait-landscape.rb +7 -7
  41. data/samples/ranges.rb +13 -14
  42. data/samples/save_pdf.rb +2 -2
  43. data/samples/text_options.rb +17 -17
  44. data/samples/tgc_proofs.rb +3 -3
  45. data/samples/use_layout.rb +3 -3
  46. data/spec/api/api_text_spec.rb +11 -17
  47. data/spec/commands/new_spec.rb +10 -10
  48. data/spec/data/easy-circular-extends.yml +1 -1
  49. data/spec/data/hard-circular-extends.yml +2 -2
  50. data/spec/data/multi-extends-single-entry.yml +3 -3
  51. data/spec/data/multi-level-extends.yml +1 -1
  52. data/spec/data/no-extends.yml +2 -2
  53. data/spec/data/pre-extends.yml +1 -1
  54. data/spec/data/self-circular-extends.yml +1 -1
  55. data/spec/data/single-extends.yml +1 -1
  56. data/spec/data/single-level-multi-extends.yml +1 -1
  57. data/spec/deck_spec.rb +62 -62
  58. data/spec/graphics/graphics_images_spec.rb +79 -0
  59. data/spec/graphics/graphics_save_doc_spec.rb +66 -0
  60. data/spec/graphics/graphics_shapes_spec.rb +74 -0
  61. data/spec/graphics/graphics_text_spec.rb +135 -0
  62. data/spec/input_helpers_spec.rb +61 -40
  63. data/spec/samples_run_spec.rb +6 -6
  64. data/spec/spec_helper.rb +32 -1
  65. data/squib.gemspec +21 -21
  66. metadata +22 -14
@@ -9,19 +9,20 @@ module Squib
9
9
  # @option opts file [String] the name of the PDF file to save. See {file:README.md#Specifying_Files Specifying Files}
10
10
  # @option opts dir [String] (_output) the directory to save to. Created if it doesn't exist.
11
11
  # @option opts margin [Integer] (75) the margin around the outside of the page
12
- # @option opts gap [Integer] (0) the space in pixels between the cards
12
+ # @option opts gap [Integer] (0) the space in pixels between the cards
13
13
  # @option opts trim [Integer] (0) the space around the edge of each card to trim (e.g. to cut off the bleed margin for print-and-play)
14
14
  # @return [nil]
15
15
  # @api public
16
16
  def save_pdf(opts = {})
17
- p = needs(opts, [:file_to_save, :creatable_dir, :margin, :gap, :trim])
18
- width = 11 * @dpi ; height = 8.5 * @dpi #TODO: allow this to be specified too
17
+ p = needs(opts, [:range, :file_to_save, :creatable_dir, :margin, :gap, :trim])
18
+ width = 11 * @dpi
19
+ height = 8.5 * @dpi #TODO: allow this to be specified too
19
20
  cc = Cairo::Context.new(Cairo::PDFSurface.new("#{p[:dir]}/#{p[:file]}", width, height))
20
- x = p[:margin] ; y = p[:margin]
21
-
21
+ x = p[:margin]
22
+ y = p[:margin]
22
23
  @progress_bar.start("Saving PDF to #{p[:dir]}/#{p[:file]}", p[:range].size) do |bar|
23
- @cards.each_with_index do |card, i|
24
- surface = trim(card.cairo_surface, p[:trim], @width, @height)
24
+ p[:range].each do |i|
25
+ surface = trim(@cards[i].cairo_surface, p[:trim], @width, @height)
25
26
  cc.set_source(surface, x, y)
26
27
  cc.paint
27
28
  bar.increment
@@ -30,16 +31,17 @@ module Squib
30
31
  x = p[:margin]
31
32
  y += surface.height + p[:gap]
32
33
  if y > (height - surface.height - p[:margin])
33
- x = p[:margin] ; y = p[:margin]
34
+ x = p[:margin]
35
+ y = p[:margin]
34
36
  cc.show_page #next page
35
37
  end
36
38
  end
37
39
  end
38
- end
40
+ end
39
41
  end
40
42
 
41
43
  # :nodoc:
42
- # @api private
44
+ # @api private
43
45
  def trim(surface, trim, width, height)
44
46
  if trim > 0
45
47
  tmp = Cairo::ImageSurface.new(width-2*trim, height-2*trim)
@@ -52,4 +54,4 @@ module Squib
52
54
  end
53
55
 
54
56
  end
55
- end
57
+ end
@@ -2,7 +2,7 @@ module Squib
2
2
  class Card
3
3
 
4
4
  # :nodoc:
5
- # @api private
5
+ # @api private
6
6
  def save_png(i, dir, prefix, do_rotate, angle)
7
7
  if [true, :clockwise, :counterclockwise].include?(do_rotate)
8
8
  surface = rotated_image(angle)
@@ -24,10 +24,10 @@ module Squib
24
24
  rotated_cc.target
25
25
  end
26
26
  # :nodoc:
27
- # @api private
27
+ # @api private
28
28
  def write_png(surface, i, dir, prefix)
29
29
  surface.write_to_png("#{dir}/#{prefix}#{i}.png")
30
30
  end
31
31
 
32
32
  end
33
- end
33
+ end
@@ -1,10 +1,11 @@
1
1
  module Squib
2
2
  class Card
3
-
3
+
4
4
  # :nodoc:
5
- # @api private
5
+ # @api private
6
6
  def rect(x, y, width, height, x_radius, y_radius, fill_color, stroke_color, stroke_width)
7
- width=@width if width==:native; height=@height if height==:native
7
+ width = @width if width == :native
8
+ height = @height if height == :native
8
9
  use_cairo do |cc|
9
10
  cc.rounded_rectangle(x, y, width, height, x_radius, y_radius)
10
11
  cc.set_source_color(stroke_color)
@@ -17,7 +18,7 @@ module Squib
17
18
  end
18
19
 
19
20
  # :nodoc:
20
- # @api private
21
+ # @api private
21
22
  def circle(x, y, radius, fill_color, stroke_color, stroke_width)
22
23
  use_cairo do |cc|
23
24
  cc.circle(x, y, radius)
@@ -31,7 +32,7 @@ module Squib
31
32
  end
32
33
 
33
34
  # :nodoc:
34
- # @api private
35
+ # @api private
35
36
  def triangle(x1, y1, x2, y2, x3, y3, fill_color, stroke_color, stroke_width)
36
37
  use_cairo do |cc|
37
38
  cc.triangle(x1, y1, x2, y2, x3, y3)
@@ -45,7 +46,7 @@ module Squib
45
46
  end
46
47
 
47
48
  # :nodoc:
48
- # @api private
49
+ # @api private
49
50
  def line(x1, y1, x2, y2, stroke_color, stroke_width)
50
51
  use_cairo do |cc|
51
52
  cc.move_to(x1, y1)
@@ -55,6 +56,6 @@ module Squib
55
56
  cc.stroke
56
57
  end
57
58
  end
58
-
59
+
59
60
  end
60
- end
61
+ end
@@ -4,114 +4,116 @@ module Squib
4
4
  class Card
5
5
 
6
6
  # :nodoc:
7
- # @api private
8
- def draw_text_hint(x,y,layout, color)
7
+ # @api private
8
+ def draw_text_hint(cc,x,y,layout, color,angle)
9
9
  color = @deck.text_hint if color.to_s.eql? 'off' and not @deck.text_hint.to_s.eql? 'off'
10
- return if color.to_s.eql? 'off'
10
+ return if color.to_s.eql? 'off' or color.nil?
11
11
  # when w,h < 0, it was never set. extents[1] are ink extents
12
12
  w = layout.width / Pango::SCALE
13
13
  w = layout.extents[1].width / Pango::SCALE if w < 0
14
14
  h = layout.height / Pango::SCALE
15
15
  h = layout.extents[1].height / Pango::SCALE if h < 0
16
- rect(x,y,w,h,0,0,'#0000',color, 2.0)
16
+ cc.rounded_rectangle(x,y,w,h,0,0)
17
+ cc.set_source_color(color)
18
+ cc.set_line_width(2.0)
19
+ cc.stroke
17
20
  end
18
21
 
19
22
  # :nodoc:
20
- # @api private
21
- def ellipsize(layout, ellipsize)
22
- unless ellipsize.nil?
23
- h = { :none => Pango::Layout::ELLIPSIZE_NONE,
24
- :start => Pango::Layout::ELLIPSIZE_START,
25
- :middle => Pango::Layout::ELLIPSIZE_MIDDLE,
26
- :end => Pango::Layout::ELLIPSIZE_END,
27
- true => Pango::Layout::ELLIPSIZE_END,
28
- false => Pango::Layout::ELLIPSIZE_NONE
29
- }
30
- layout.ellipsize = h[ellipsize]
23
+ # @api private
24
+ def set_ellipsize!(layout, ellipsize)
25
+ case ellipsize.to_s.downcase
26
+ when 'none', 'false'
27
+ layout.ellipsize = Pango::Layout::ELLIPSIZE_NONE
28
+ when 'start'
29
+ layout.ellipsize = Pango::Layout::ELLIPSIZE_START
30
+ when 'middle'
31
+ layout.ellipsize = Pango::Layout::ELLIPSIZE_MIDDLE
32
+ when 'end', 'true'
33
+ layout.ellipsize = Pango::Layout::ELLIPSIZE_END
31
34
  end
32
- layout
33
35
  end
34
36
 
35
37
  # :nodoc:
36
- # @api private
37
- def wrap(layout, wrap)
38
- unless wrap.nil?
39
- h = { :word => Pango::Layout::WRAP_WORD,
40
- :char => Pango::Layout::WRAP_CHAR,
41
- :word_char => Pango::Layout::WRAP_WORD_CHAR,
42
- true => Pango::Layout::WRAP_WORD_CHAR,
43
- false => nil,
44
- :none => nil
45
- }
46
- layout.wrap = h[wrap]
38
+ # @api private
39
+ def set_wrap!(layout, wrap)
40
+ case wrap.to_s.downcase
41
+ when 'word'
42
+ layout.wrap = Pango::Layout::WRAP_WORD
43
+ when 'char'
44
+ layout.wrap = Pango::Layout::WRAP_CHAR
45
+ when 'word_char', 'true'
46
+ layout.wrap = Pango::Layout::WRAP_WORD_CHAR
47
47
  end
48
- layout
49
48
  end
50
49
 
51
50
  # :nodoc:
52
- # @api private
53
- def align(layout, align)
54
- unless align.nil?
55
- h = { :left => Pango::ALIGN_LEFT,
56
- :right => Pango::ALIGN_RIGHT,
57
- :center => Pango::ALIGN_CENTER
58
- }
59
- layout.alignment = h[align]
51
+ # @api private
52
+ def set_align!(layout, align)
53
+ case align.to_s.downcase
54
+ when 'left'
55
+ layout.alignment = Pango::ALIGN_LEFT
56
+ when 'right'
57
+ layout.alignment = Pango::ALIGN_RIGHT
58
+ when 'center'
59
+ layout.alignment = Pango::ALIGN_CENTER
60
60
  end
61
- layout
62
61
  end
63
62
 
64
63
  # :nodoc:
65
- # @api private
66
- def valign(cc, layout, x, y, valign)
67
- if layout.height > 0
64
+ # @api private
65
+ def valign!(cc, layout, x, y, valign)
66
+ if layout.height > 0
68
67
  ink_extents = layout.extents[1]
69
- case valign
70
- when :middle
68
+ case valign.to_s
69
+ when 'middle'
71
70
  cc.move_to(x, y + (layout.height - ink_extents.height) / (2 * Pango::SCALE))
72
- when :bottom
71
+ when 'bottom'
73
72
  cc.move_to(x, y + (layout.height - ink_extents.height) / Pango::SCALE)
74
73
  end
75
74
  end
76
75
  end
77
76
 
78
77
  # :nodoc:
79
- # @api private
80
- def setwh(layout, width, height)
78
+ # @api private
79
+ def set_wh!(layout, width, height)
81
80
  layout.width = width * Pango::SCALE unless width.nil? || width == :native
82
81
  layout.height = height * Pango::SCALE unless height.nil? || height == :native
83
82
  layout
84
83
  end
85
84
 
86
85
  # :nodoc:
87
- # @api private
88
- def text(str, font, font_size, color,
86
+ # @api private
87
+ def text(str, font, font_size, color,
89
88
  x, y, width, height,
90
- markup, justify, wrap, ellipsize,
89
+ markup, justify, wrap, ellipsize,
91
90
  spacing, align, valign, hint, angle)
92
- Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, rotate: #{rotation} etc."}
91
+ Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, angle: #{angle} etc."}
93
92
  use_cairo do |cc|
94
93
  cc.set_source_color(color)
95
- cc.move_to(x,y)
94
+ cc.translate(x,y)
96
95
  cc.rotate(angle)
96
+ cc.translate(-1*x,-1*y)
97
+ cc.move_to(x,y)
98
+
97
99
  layout = cc.create_pango_layout
98
100
  font_desc = Pango::FontDescription.new(font)
99
101
  font_desc.size = font_size * Pango::SCALE unless font_size.nil?
100
102
  layout.font_description = font_desc
101
103
  layout.text = str.to_s
102
104
  layout.markup = str.to_s if markup
103
- layout = setwh(layout, width, height)
104
- layout = wrap(layout, wrap)
105
- layout = ellipsize(layout, ellipsize)
106
- layout = align(layout, align)
105
+ set_wh!(layout, width, height)
106
+ set_wrap!(layout, wrap)
107
+ set_ellipsize!(layout, ellipsize)
108
+ set_align!(layout, align)
107
109
  layout.justify = justify unless justify.nil?
108
- layout.spacing = spacing * Pango::SCALE unless spacing.nil?
109
- cc.update_pango_layout(layout)
110
- valign(cc, layout, x,y, valign)
110
+ layout.spacing = spacing * Pango::SCALE unless spacing.nil?
111
+ cc.update_pango_layout(layout)
112
+ valign!(cc, layout, x, y, valign)
111
113
  cc.update_pango_layout(layout) ; cc.show_pango_layout(layout)
112
- draw_text_hint(x,y,layout,hint)
114
+ draw_text_hint(cc,x,y,layout,hint,angle)
113
115
  end
114
116
  end
115
117
 
116
118
  end
117
- end
119
+ end
@@ -8,11 +8,11 @@ module Squib
8
8
  # :nodoc:
9
9
  # @api private
10
10
  def needs(opts, params)
11
- Squib.logger.debug {"Given opts: #{opts}"}
11
+ Squib.logger.debug {"Method #{caller(1,1)} was given the following opts: #{opts}"}
12
12
  opts = layoutify(opts) if params.include? :layout
13
13
  opts = Squib::SYSTEM_DEFAULTS.merge(opts)
14
14
  opts = expand_singletons(opts, params)
15
- opts = rangeify(opts) if params.include? :range
15
+ opts = rangeify(opts) if params.include? :range
16
16
  opts = fileify(opts) if params.include? :file
17
17
  opts = fileify(opts, false) if params.include? :file_to_save
18
18
  opts = colorify(opts, true) if params.include? :nillable_color
@@ -37,7 +37,7 @@ module Squib
37
37
  Squib::EXPANDING_PARAMS.each_pair do |param_name, api_param|
38
38
  if needed_params.include? param_name
39
39
  unless opts[api_param].respond_to?(:each)
40
- opts[api_param] = [opts[api_param]] * @cards.size
40
+ opts[api_param] = [opts[api_param]] * @cards.size
41
41
  end
42
42
  end
43
43
  end
@@ -50,8 +50,8 @@ module Squib
50
50
  # :nodoc:
51
51
  # @api private
52
52
  def layoutify(opts)
53
- unless opts[:layout].respond_to?(:each)
54
- opts[:layout] = [opts[:layout]] * @cards.size
53
+ unless opts[:layout].respond_to?(:each)
54
+ opts[:layout] = [opts[:layout]] * @cards.size
55
55
  end
56
56
  opts[:layout].each_with_index do |layout, i|
57
57
  unless layout.nil?
@@ -61,7 +61,7 @@ module Squib
61
61
  opts[key.to_sym] = [] if opts[key.to_sym].nil?
62
62
  opts[key.to_sym][i] ||= entry[key] #don't override if it's already there
63
63
  end
64
- else
64
+ else
65
65
  Squib.logger.warn ("Layout entry '#{layout}' does not exist." )
66
66
  end
67
67
  end
@@ -99,7 +99,7 @@ module Squib
99
99
  # @api private
100
100
  def fileify(opts, file_must_exist=true)
101
101
  [opts[:file]].flatten.each do |file|
102
- if file_must_exist and !File.exists?(file)
102
+ if file_must_exist and !File.exists?(file)
103
103
  raise "File #{File.expand_path(file)} does not exist!"
104
104
  end
105
105
  end
@@ -112,9 +112,9 @@ module Squib
112
112
  def dirify(opts, key, allow_create=false)
113
113
  return opts if Dir.exists?(opts[key])
114
114
  if allow_create
115
- Squib.logger.warn {"Dir #{opts[key]} does not exist, creating it."}
115
+ Squib.logger.warn("Dir '#{opts[key]}' does not exist, creating it.")
116
116
  Dir.mkdir opts[key]
117
- return opts
117
+ return opts
118
118
  else
119
119
  raise "'#{opts[key]}' does not exist!"
120
120
  end
@@ -145,14 +145,14 @@ module Squib
145
145
  opts[:font][i] = Squib::SYSTEM_DEFAULTS[:default_font] if font == :default
146
146
  end
147
147
  Squib.logger.debug {"After fontify: #{opts}"}
148
- opts
148
+ opts
149
149
  end
150
- module_function :fontify
150
+ module_function :fontify
151
151
 
152
152
  # :nodoc:
153
153
  # @api private
154
154
  def radiusify(opts)
155
- opts[:radius].each_with_index do |radius, i|
155
+ opts[:radius].each_with_index do |radius, i|
156
156
  unless radius.nil?
157
157
  opts[:x_radius][i] = radius
158
158
  opts[:y_radius][i] = radius
@@ -191,4 +191,4 @@ module Squib
191
191
  module_function :svgidify
192
192
 
193
193
  end
194
- end
194
+ end
@@ -23,16 +23,16 @@ module Squib
23
23
  @enabled = enabled
24
24
  end
25
25
 
26
- def start(title="", total=100, &block)
26
+ def start(title='', total=100, &block)
27
27
  if @enabled
28
- @bar = ProgressBar.create(title: title, total: total, format: '%t <%B> %p%% %a')
28
+ @bar = ProgressBar.create(title: title, total: total, format: '%t <%B> %p%% %a')
29
29
  yield(@bar)
30
30
  @bar.finish
31
- else
31
+ else
32
32
  yield(Squib::DoNothing.new)
33
33
  end
34
34
  end
35
35
  end
36
36
 
37
37
 
38
- end
38
+ end
@@ -1,3 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'squib'
3
+ gem 'squib'
@@ -1,6 +1,6 @@
1
1
  require 'squib'
2
2
 
3
- Squib::Deck.new(cards: 3, layout: 'layout.yml') do
4
- text str: "Hello, World!"
3
+ Squib::Deck.new(cards: 3, layout: 'layout.yml') do
4
+ text str: 'Hello, World!'
5
5
  save format: :png
6
- end
6
+ end
data/lib/squib/version.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  module Squib
2
2
 
3
3
  # The next version to be released.
4
- # Uses semantic versioning
5
- VERSION = "0.0.4"
4
+ # Uses semantic versioning: http://semver.org/
5
+ #
6
+ # Most of the time this is in the alpha of the next release.
7
+ # e.g. v0.0.5a is on its way to becoming v0.0.5
8
+ #
9
+ VERSION = '0.0.5'
6
10
  end
@@ -1,7 +1,7 @@
1
1
  require 'squib'
2
2
 
3
- # Here's an exmaple of being able to scale a font
4
- # based on the length of individual string.
3
+ # Here's an exmaple of being able to scale a font
4
+ # based on the length of individual string.
5
5
  # Handy for making minor font scales to fill text boxes.
6
6
  def autoscale(str_array)
7
7
  str_array.inject([]) do | memo, str |
@@ -21,7 +21,7 @@ Squib::Deck.new(cards: 3) do
21
21
 
22
22
  title = %w(ShortBig Medium_Length_Name Super_Duper_Long_Name)
23
23
  text str: title, x: 65, y: 400, align: :center, width: 700,
24
- font: 'Arial', font_size: autoscale(title), hint: :red
24
+ font: 'Arial', font_size: autoscale(title), hint: :red
25
25
 
26
26
  save prefix: 'autoscale_', format: :png
27
- end
27
+ end