squib 0.15.3 → 0.16.0.pre.preview1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests.yml +22 -0
  3. data/CHANGELOG.md +22 -0
  4. data/Dockerfile +18 -16
  5. data/Guardfile +8 -0
  6. data/README.md +3 -9
  7. data/RELEASE TODO.md +1 -0
  8. data/Rakefile +3 -0
  9. data/lib/squib.rb +3 -1
  10. data/lib/squib/args/arg_loader.rb +109 -106
  11. data/lib/squib/args/box.rb +52 -48
  12. data/lib/squib/args/card_range.rb +26 -24
  13. data/lib/squib/args/color_validator.rb +4 -9
  14. data/lib/squib/args/coords.rb +39 -25
  15. data/lib/squib/args/csv_opts.rb +13 -16
  16. data/lib/squib/args/dir_validator.rb +7 -12
  17. data/lib/squib/args/draw.rb +69 -68
  18. data/lib/squib/args/embed_adjust.rb +12 -15
  19. data/lib/squib/args/embed_key.rb +6 -11
  20. data/lib/squib/args/hand_special.rb +25 -25
  21. data/lib/squib/args/import.rb +54 -27
  22. data/lib/squib/args/input_file.rb +22 -26
  23. data/lib/squib/args/paint.rb +30 -31
  24. data/lib/squib/args/paragraph.rb +95 -93
  25. data/lib/squib/args/save_batch.rb +50 -48
  26. data/lib/squib/args/scale_box.rb +43 -39
  27. data/lib/squib/args/sheet.rb +147 -149
  28. data/lib/squib/args/showcase_special.rb +32 -32
  29. data/lib/squib/args/sprue_file.rb +30 -30
  30. data/lib/squib/args/svg_special.rb +26 -26
  31. data/lib/squib/args/transform.rb +48 -54
  32. data/lib/squib/args/typographer.rb +88 -92
  33. data/lib/squib/args/unit_conversion.rb +6 -8
  34. data/lib/squib/args/xywh_shorthands.rb +56 -0
  35. data/lib/squib/builtin/projects/advanced/config.yml +4 -3
  36. data/lib/squib/builtin/projects/basic/config.yml +4 -3
  37. data/lib/squib/conf.rb +5 -0
  38. data/lib/squib/deck.rb +34 -12
  39. data/lib/squib/dsl/background.rb +35 -0
  40. data/lib/squib/dsl/circle.rb +39 -0
  41. data/lib/squib/dsl/csv.rb +42 -0
  42. data/lib/squib/dsl/curve.rb +35 -0
  43. data/lib/squib/dsl/cut_zone.rb +47 -0
  44. data/lib/squib/dsl/ellipse.rb +37 -0
  45. data/lib/squib/dsl/grid.rb +35 -0
  46. data/lib/squib/{api → dsl}/groups.rb +0 -0
  47. data/lib/squib/dsl/hand.rb +42 -0
  48. data/lib/squib/dsl/line.rb +35 -0
  49. data/lib/squib/dsl/png.rb +56 -0
  50. data/lib/squib/dsl/polygon.rb +36 -0
  51. data/lib/squib/dsl/rect.rb +37 -0
  52. data/lib/squib/dsl/safe_zone.rb +48 -0
  53. data/lib/squib/dsl/save.rb +21 -0
  54. data/lib/squib/dsl/save_pdf.rb +50 -0
  55. data/lib/squib/dsl/save_png.rb +47 -0
  56. data/lib/squib/dsl/save_sheet.rb +53 -0
  57. data/lib/squib/dsl/showcase.rb +43 -0
  58. data/lib/squib/dsl/star.rb +37 -0
  59. data/lib/squib/dsl/svg.rb +62 -0
  60. data/lib/squib/dsl/text.rb +54 -0
  61. data/lib/squib/dsl/text_embed.rb +78 -0
  62. data/lib/squib/dsl/triangle.rb +35 -0
  63. data/lib/squib/{api → dsl}/units.rb +10 -0
  64. data/lib/squib/dsl/xlsx.rb +40 -0
  65. data/lib/squib/dsl/yaml.rb +40 -0
  66. data/lib/squib/errors_warnings/warn_unexpected_params.rb +14 -0
  67. data/lib/squib/graphics/save_images.rb +3 -3
  68. data/lib/squib/graphics/save_sprue.rb +14 -2
  69. data/lib/squib/graphics/text.rb +37 -9
  70. data/lib/squib/import/csv_importer.rb +45 -0
  71. data/lib/squib/import/quantity_exploder.rb +18 -0
  72. data/lib/squib/import/xlsx_importer.rb +28 -0
  73. data/lib/squib/import/yaml_importer.rb +30 -0
  74. data/lib/squib/layout_parser.rb +24 -7
  75. data/lib/squib/sprues/crop_line.rb +6 -6
  76. data/lib/squib/sprues/crop_line_dash.rb +6 -6
  77. data/lib/squib/sprues/sprue.rb +16 -14
  78. data/lib/squib/version.rb +1 -1
  79. data/samples/autoscale_font/_autoscale_font.rb +77 -8
  80. data/samples/colors/_switch_color.rb +2 -2
  81. data/samples/data/_excel.rb +1 -1
  82. data/samples/ranges/_ranges.rb +1 -1
  83. data/samples/saves/_save_filenames.rb +4 -0
  84. data/samples/saves/_save_pdf.rb +1 -1
  85. data/samples/saves/_saves.rb +2 -1
  86. data/samples/shapes/_draw_shapes.rb +2 -2
  87. data/samples/sprues/_builtin_sprues.rb +1 -0
  88. data/samples/sprues/_fold_sheet.rb +4 -1
  89. data/samples/text/_text.rb +6 -1
  90. data/samples/text/_text_options.rb +2 -1
  91. data/samples/units/_cells.rb +51 -0
  92. data/samples/units/_shorthands.rb +49 -0
  93. data/samples/units/_units.rb +7 -0
  94. data/squib.gemspec +11 -5
  95. metadata +120 -33
  96. data/.travis.yml +0 -17
  97. data/appveyor.yml +0 -25
  98. data/lib/squib/api/background.rb +0 -15
  99. data/lib/squib/api/data.rb +0 -137
  100. data/lib/squib/api/image.rb +0 -49
  101. data/lib/squib/api/save.rb +0 -83
  102. data/lib/squib/api/shapes.rb +0 -124
  103. data/lib/squib/api/text.rb +0 -25
  104. data/lib/squib/api/text_embed.rb +0 -71
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e9214c505f044e2a2c495c56f8561791a19cbbf92100f17b9b2c558e353b279
4
- data.tar.gz: d85206902341999fd4c0f4cdcb2cb3f2f6e649a4d6031369af4f747302826d30
3
+ metadata.gz: 24cc3f2b97503042d0ad1a0db003e8cb585e4853389c78b49c54c036f45bf4e2
4
+ data.tar.gz: aa49287f4fa01039f4ea8737e862d24637ba47142d84849e54335b44b00f4424
5
5
  SHA512:
6
- metadata.gz: aae369ed29a073c2469ea665e1ecd249d29b555a7c2c3d45c30a610d515779beea46c0438f9bca4541c0ab46c0745f1948c27995163be1cf40fa99f006cfa9b8
7
- data.tar.gz: '0392fbf16c9078aa8f477fc521724a1c9f3b0903ae2317f2543e4cf05d3fa16d981e8ac789abe391952281c8483789dcc828c3a9627571ae6ec9a840720d89d9'
6
+ metadata.gz: 529665761713e33f8743356a90af15ab244e8e09ffbb4836d1aa3dd1e0398cba320ffb0e443aff355cc71604146f03865b413c3307a76d372860a07b35a8bb2b
7
+ data.tar.gz: 0fe62d7d34630c98c2750e5da46d4fd5633692f6f5cab22248b4650e6f8bfa2964ac0c107f5efd847c44342ad7b2ccf41634719b6c6cf84a55154ca1bcaba405
@@ -0,0 +1,22 @@
1
+ name: Squib Unit Tests
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ os: [ubuntu, macos]
11
+ ruby: [2.5, 2.6, 2.7, head]
12
+ runs-on: ${{ matrix.os }}-latest
13
+ continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ # bundler-cache: true # runs 'bundle install' and caches installed gems automatically
20
+ - run: ruby --version # explicitly show the ruby version
21
+ - run: bundle install
22
+ - run: bundle exec rake
@@ -3,6 +3,28 @@ Squib follows [semantic versioning](http://semver.org).
3
3
 
4
4
  ## v0.16.0 / Unreleased
5
5
 
6
+ Features:
7
+ * Special custom unit: cells. A "cell" defaults to 37.5px, or 1/8in, e.g. `x: '1 cell'` means `x: 37.5`. See the docs for details.
8
+ * Shorthands for `x`, `y`, `width`, and `height`! The words `x: 'middle'` and `x: 'middle + 1in'` will get interpreted. See the docs for details.
9
+ * Autoscaling text! `ellipsize: :autoscale` will now downscale your `font_size` if the text ellipsized. Thanks @Qgel! (#288, #111).
10
+ * Option checking!! Completely reworked the way we handle arguments in Squib internally (no external behavioral differences). Now, when you give an option to Squib that is not expected. Since every DSL method "knows" what options it takes, that also means we have EVERY option properly documented (missed a few...) AND we have an automated test that will tell us if we forget to document it.
11
+ * `save_png` and `save_sheet` now have a `suffix` option which defaults to `''`. So now you can customize the filenames with `prefix`, `count_format`, and `suffix`.
12
+
13
+ Compatibility:
14
+ * When saving PNGs with sprues, outputs start counting at zero - which is more consistent with the rest of Squib.
15
+ * Minimum Ruby is now 2.5. NOTE: Ruby 3.0 is coming Christmas 2020!! Check it out.
16
+
17
+ Bugs:
18
+ * Extra page/no page issue with sprues (#320)
19
+ * Fix Ruby 2.7+ deprecations with CSV arguments (#303)
20
+
21
+ Chores:
22
+ * Reorganized the code internally. (#298) Every DSL method now has its own file.
23
+ * Moved to Github Actions
24
+ * Bump pango et al
25
+
26
+
27
+
6
28
  ## v0.15.3 / 2019-10-17
7
29
 
8
30
  Chores:
data/Dockerfile CHANGED
@@ -1,25 +1,27 @@
1
- FROM ruby:2.5-alpine
1
+ # This is the official Squib Docker image.
2
+ #
3
+ FROM ruby:2.7-slim
2
4
  WORKDIR /usr/src/app
3
5
 
4
6
  LABEL org.squib.url=http://squib.rocks \
5
7
  org.squib.github=https://github.com/andymeneely/squib
6
8
 
7
- RUN apk --no-cache add --update \
9
+ RUN apt-get update && \
10
+ apt-get install -y \
11
+ libgirepository1.0-dev \
12
+ build-essential \
8
13
  ruby-dev \
9
- build-base \
10
- libxml2-dev \
11
- libxslt-dev \
12
- pcre-dev \
13
- libffi-dev \
14
- cairo
14
+ ruby \
15
+ ruby-gdk-pixbuf2 \
16
+ git \
17
+ fonts-open-sans
15
18
 
16
- # Just for devving on
17
- COPY . /app
19
+ # Build the current directory of Squib
20
+ COPY . /usr/src/app
21
+ RUN rm -f /usr/src/app/Gemfile.lock
22
+ RUN gem install bundler
23
+ RUN bundle install
24
+ RUN bundle exec rake install
18
25
 
19
- CMD ["sh"]
26
+ # ENTRYPOINT [ "sh" ]
20
27
 
21
- # RUN gem install \
22
- # squib \
23
- # -- --use-system-libraries
24
-
25
- # NOTE: STILL UNDER DEVELOPMENT! Don't use this just yet.
@@ -0,0 +1,8 @@
1
+ group :default do
2
+ guard 'rake', :task => 'spec' do
3
+ watch %r{.*\.xlsx$}
4
+ watch %r{.*\.rb$}
5
+ watch %r{.*\.yml$}
6
+ watch %r{.*\.rst$}
7
+ end
8
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Squib [![Gem Version](https://badge.fury.io/rb/squib.svg)](https://rubygems.org/gems/squib) [![Build Status](https://secure.travis-ci.org/andymeneely/squib.svg?branch=master)](https://travis-ci.org/andymeneely/squib) [![Build status](https://ci.appveyor.com/api/projects/status/ptjw6fvjh73anlau/branch/master?svg=true)](https://ci.appveyor.com/project/andymeneely/squib/branch/master) [![Coverage Status](https://img.shields.io/coveralls/andymeneely/squib.svg)](https://coveralls.io/r/andymeneely/squib) [![ReadTheDocs](https://readthedocs.org/projects/squib/badge/?version=latest)](http://squib.readthedocs.io/en/latest/?badge=latest) [![BoardGameGeek](https://cdn.rawgit.com/andymeneely/squib/gh-pages/images/microbadge.png)](https://boardgamegeek.com/guild/2601)
1
+ # Squib [![Gem Version](https://badge.fury.io/rb/squib.svg)](https://rubygems.org/gems/squib) [![Build Status](https://secure.travis-ci.org/andymeneely/squib.svg?branch=master)](https://travis-ci.org/andymeneely/squib) [![Build status](https://ci.appveyor.com/api/projects/status/ptjw6fvjh73anlau/branch/master?svg=true)](https://ci.appveyor.com/project/andymeneely/squib/branch/master) [![Coverage Status](https://img.shields.io/coveralls/andymeneely/squib.svg)](https://coveralls.io/r/andymeneely/squib) [![ReadTheDocs](https://readthedocs.org/projects/squib/badge/?version=latest)](http://squib.readthedocs.io/en/latest/?badge=latest) [![BoardGameGeek](https://github.com/andymeneely/squib.rocks/raw/gh-pages/images/microbadge.png)](https://boardgamegeek.com/guild/2601)
2
2
 
3
3
  Squib is a Ruby [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for prototyping card and board games. Write a little bit of Ruby, define your deck's stats, then compile your game into a series of images ready for print-and-play or even print-on-demand. Squib is very data-driven and built on the principle of Don't Repeat Yourself. Think of it like [nanDeck](http://www.nand.it/nandeck/) done "the Ruby way". Squib supports:
4
4
 
@@ -31,7 +31,7 @@ Wanna see more? Check out the website: http://andymeneely.github.io/squib/
31
31
 
32
32
  ## Installation
33
33
 
34
- Squib requires Ruby 2.4 or later.
34
+ Squib requires Ruby 2.5 or later.
35
35
 
36
36
  Install it yourself with:
37
37
 
@@ -85,7 +85,7 @@ Go [read the docs!](http://squib.readthedocs.org/)
85
85
 
86
86
  Also:
87
87
  * The `samples` directory in the [source repository](https://github.com/andymeneely/squib) has lots of examples.
88
- * [Your Last Heist](http://yourlastheist.com) is my own creation, and it was made with Squib. Go through the repository and watch how it evolved!
88
+ * [Masters of the Heist](http://mastersoftheheist.com) is my own creation, and it was made with Squib. Go through the repository and watch how it evolved!
89
89
  * [Junk Land](https://github.com/andymeneely/junk-land) is my own creation that's uses Squib for full-color rendering, and makes use of Ruby in a lot of interesting ways. The port is still in process.
90
90
  * [Project Spider Monkey](https://github.com/andymeneely/project-spider-monkey) is another of my own creations. This one was started from scratch with Squib, but it's still in its early stages.
91
91
 
@@ -99,12 +99,6 @@ Squib tries to keep you DRY (Don't Repeat Yourself) with the following features:
99
99
  * Custom colors keep you from hardcoding magic color strings everywhere. Custom colors go into `config.yml` file.
100
100
  * Plus, you know, Ruby.
101
101
 
102
- ## SublimeText
103
-
104
- Using SublimeText? I like you already. I've written up some Squib snippets to ease remembering Squib commands. It's called `Squib Snippets` on Package Control. Compatible with SublimeText 3. Source code is also [on Github](https://github.com/andymeneely/sublime-squib) (contributions welcome!). Check it out:
105
-
106
- ![Sublime Squib Snippets](https://raw.githubusercontent.com/andymeneely/squib/screencasts/sublime-squib-snippets.gif)
107
-
108
102
 
109
103
  ## Docker
110
104
 
@@ -15,6 +15,7 @@ Be sure to remember to do the following for releases. (Copy into a GitHub issue)
15
15
  - [ ] Push master and release branches
16
16
  - [ ] Create GitHub release tag
17
17
  - [ ] `gem push pkg/squib-x.y.z.gem`
18
+ - [ ] `gem push --key github --host https://rubygems.pkg.github.com/andymeneely pkg/squib-x.y.z.gem`
18
19
  - [ ] Github milestone closed
19
20
  - [ ] Activate version on squib.readthedocs.org
20
21
  - [ ] Bump version.rb to the next alpha
data/Rakefile CHANGED
@@ -6,6 +6,9 @@ require 'benchmark'
6
6
  desc 'install + spec'
7
7
  task default: ['install:local', :spec]
8
8
 
9
+ desc 'test => spec'
10
+ task test: [:spec]
11
+
9
12
  # Useful for hooking up with SublimeText.
10
13
  # e.g. rake sample[basic.rb]
11
14
  desc 'Run a specific sample'
@@ -2,12 +2,14 @@ require 'logger'
2
2
  require 'cairo'
3
3
  require 'pango'
4
4
  require 'rsvg2'
5
+ require 'rainbow/refinement'
5
6
  require_relative 'squib/version'
6
7
  require_relative 'squib/commands/cli'
7
8
  require_relative 'squib/deck'
8
9
  require_relative 'squib/card'
9
10
 
10
11
  module Squib
12
+ using Rainbow # we can colorize strings now!
11
13
 
12
14
  # Access the internal logger that Squib uses. By default, Squib configure the logger to the WARN level
13
15
  # Use this to suppress or increase output levels.
@@ -22,7 +24,7 @@ module Squib
22
24
  @logger = Logger.new($stdout)
23
25
  @logger.level = Logger::WARN
24
26
  @logger.formatter = proc do |severity, datetime, m_progname, msg|
25
- "#{datetime} #{severity}: #{msg}\n"
27
+ "[#{datetime.strftime('%F %H:%M:%S')} #{severity.red}] #{msg}\n"
26
28
  end
27
29
  end
28
30
  @logger
@@ -2,125 +2,128 @@ require_relative '../constants'
2
2
  require_relative '../conf'
3
3
  require 'ostruct'
4
4
 
5
- module Squib
6
- # @api private
7
- module Args
5
+ # Intended to be used a a mix-in,
6
+ # For example use see Box as an example
7
+ module Squib::Args::ArgLoader
8
8
 
9
- # Intended to be used a a mix-in,
10
- # For example use see Box as an example
11
- module ArgLoader
9
+ # wrapper for compatibility
10
+ def extract!(args, deck)
11
+ @deck = deck
12
+ load!(args,
13
+ expand_by: deck.size,
14
+ layout: deck.layout,
15
+ dpi: deck.dpi,
16
+ cell_px: deck.cell_px)
17
+ end
12
18
 
13
- # Main class invoked by the client (i.e. api/ methods)
14
- def load!(args, expand_by: 1, layout: {}, dpi: 300)
15
- Squib.logger.debug { "ARG LOADER: load! for #{self.class}, args: #{args}" }
16
- @dpi = dpi
17
- args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
18
- expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
19
- validate
20
- convert_units dpi: dpi
21
- self
22
- end
19
+ # Main class invoked by the client (i.e. dsl/ methods)
20
+ def load!(args, expand_by: 1, layout: {}, dpi: 300, cell_px: 37.5)
21
+ @dpi = dpi
22
+ @cell_px = cell_px
23
+ args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
24
+ expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
25
+ validate
26
+ convert_units dpi: dpi, cell_px: cell_px
27
+ self
28
+ end
23
29
 
24
- def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
25
- attributes = self.class.parameters.keys
26
- attributes.each do |p|
27
- args[p] = defaultify(p, args, layout)
28
- val = if expandable_singleton?(p, args[p])
29
- [args[p]] * by
30
- else
31
- args[p] # not an expanding parameter
32
- end
33
- instance_variable_set "@#{p}", val
34
- end
35
- self.class.class_eval { attr_reader *(attributes) }
36
- end
30
+ def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
31
+ attributes = self.class.parameters.keys
32
+ attributes.each do |p|
33
+ args[p] = defaultify(p, args, layout)
34
+ val = if expandable_singleton?(p, args[p])
35
+ [args[p]] * by
36
+ else
37
+ args[p] # not an expanding parameter
38
+ end
39
+ instance_variable_set "@#{p}", val
40
+ end
41
+ self.class.class_eval { attr_reader *(attributes) }
42
+ end
37
43
 
38
- # Must be:
39
- # (a) an expanding parameter, and
40
- # (b) a singleton already (i.e. doesn't respond to :each)
41
- def expandable_singleton?(p, arg)
42
- self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
43
- end
44
+ # Must be:
45
+ # (a) an expanding parameter, and
46
+ # (b) a singleton already (i.e. doesn't respond to :each)
47
+ def expandable_singleton?(p, arg)
48
+ self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
49
+ end
44
50
 
45
- # Incorporate defaults and layouts
46
- # (1) Use whatever is specified if it is
47
- # (2) Go over all layout specifications (if any) and look them up
48
- # - Use layout when it's specified for that card
49
- # - Use "default" if no layout was specified, or the layout itself did not specify
50
- # Defaut can be overriden for a given dsl method (@dsl_method_defaults)
51
- # (e.g stroke width is 0.0 for text, non-zero everywhere else)
52
- #
53
- def defaultify(p, args, layout)
54
- return args[p] if args.key? p # arg was specified, no defaults used
55
- defaults = self.class.parameters.merge(@dsl_method_defaults || {})
56
- args[:layout].map do |layout_arg|
57
- return defaults[p] if layout_arg.nil? # no layout specified, use default
58
- unless layout.key? layout_arg.to_s # specified a layout, but it doesn't exist in layout. Oops!
59
- Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
60
- return defaults[p]
61
- end
62
- if layout[layout_arg.to_s].key?(p.to_s)
63
- layout[layout_arg.to_s][p.to_s] # param specified in layout
64
- else
65
- defaults[p] # layout specified, but not this param
66
- end
67
- end
51
+ # Incorporate defaults and layouts
52
+ # (1) Use whatever is specified if it is
53
+ # (2) Go over all layout specifications (if any) and look them up
54
+ # - Use layout when it's specified for that card
55
+ # - Use "default" if no layout was specified, or the layout itself did not specify
56
+ # Defaut can be overriden for a given dsl method (@dsl_method_defaults)
57
+ # (e.g stroke width is 0.0 for text, non-zero everywhere else)
58
+ #
59
+ def defaultify(p, args, layout)
60
+ return args[p] if args.key? p # arg was specified, no defaults used
61
+ defaults = self.class.parameters.merge(@dsl_method_defaults || {})
62
+ args[:layout].map do |layout_arg|
63
+ return defaults[p] if layout_arg.nil? # no layout specified, use default
64
+ unless layout.key? layout_arg.to_s # specified a layout, but it doesn't exist in layout. Oops!
65
+ Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
66
+ return defaults[p]
68
67
  end
69
-
70
- # Do singleton expansion on the layout argument as well
71
- # Treated differently since layout is not always specified
72
- def prep_layout_args(layout_args, expand_by: 1)
73
- unless layout_args.respond_to?(:each)
74
- layout_args = [layout_args] * expand_by
75
- end
76
- layout_args || []
77
- end
78
-
79
- # For each parameter/attribute foo we try to invoke a validate_foo
80
- def validate
81
- self.class.parameters.each do |param, default|
82
- method = "validate_#{param}"
83
- if self.respond_to? method
84
- attribute = "@#{param}"
85
- val = instance_variable_get(attribute)
86
- if val.respond_to? :each
87
- new_val = val.map.with_index{ |v, i| send(method, v, i) }
88
- instance_variable_set(attribute, new_val)
89
- else
90
- instance_variable_set(attribute, send(method, val))
91
- end
92
- end
93
- end
68
+ if layout[layout_arg.to_s].key?(p.to_s)
69
+ layout[layout_arg.to_s][p.to_s] # param specified in layout
70
+ else
71
+ defaults[p] # layout specified, but not this param
94
72
  end
73
+ end
74
+ end
95
75
 
96
- # Access an individual arg for a given card
97
- # @return an OpenStruct that looks just like the mixed-in class
98
- # @api private
99
- def [](i)
100
- card_arg = OpenStruct.new
101
- self.class.expanding_parameters.each do |p|
102
- p_val = instance_variable_get("@#{p}")
103
- card_arg[p] = p_val[i]
104
- end
105
- card_arg
106
- end
76
+ # Do singleton expansion on the layout argument as well
77
+ # Treated differently since layout is not always specified
78
+ def prep_layout_args(layout_args, expand_by: 1)
79
+ unless layout_args.respond_to?(:each)
80
+ layout_args = [layout_args] * expand_by
81
+ end
82
+ layout_args || []
83
+ end
107
84
 
108
- # Convert units
109
- def convert_units(dpi: 300)
110
- self.class.params_with_units.each do |p|
111
- p_str = "@#{p}"
112
- p_val = instance_variable_get(p_str)
113
- if p_val.respond_to? :each
114
- arr = p_val.map { |x| UnitConversion.parse(x, dpi) }
115
- instance_variable_set p_str, arr
116
- else
117
- instance_variable_set p_str, UnitConversion.parse(p_val, dpi)
118
- end
85
+ # For each parameter/attribute foo we try to invoke a validate_foo
86
+ def validate
87
+ self.class.parameters.each do |param, default|
88
+ method = "validate_#{param}"
89
+ if self.respond_to? method
90
+ attribute = "@#{param}"
91
+ val = instance_variable_get(attribute)
92
+ if val.respond_to? :each
93
+ new_val = val.map.with_index{ |v, i| send(method, v, i) }
94
+ instance_variable_set(attribute, new_val)
95
+ else
96
+ instance_variable_set(attribute, send(method, val))
119
97
  end
120
- self
121
98
  end
99
+ end
100
+ end
122
101
 
102
+ # Access an individual arg for a given card
103
+ # @return an OpenStruct that looks just like the mixed-in class
104
+ # @api private
105
+ def [](i)
106
+ card_arg = OpenStruct.new
107
+ self.class.expanding_parameters.each do |p|
108
+ p_val = instance_variable_get("@#{p}")
109
+ card_arg[p] = p_val[i]
123
110
  end
111
+ card_arg
112
+ end
124
113
 
114
+ # Convert units
115
+ def convert_units(dpi: 300, cell_px: 37.5)
116
+ self.class.params_with_units.each do |p|
117
+ p_str = "@#{p}"
118
+ p_val = instance_variable_get(p_str)
119
+ if p_val.respond_to? :each
120
+ arr = p_val.map { |x| Squib::Args::UnitConversion.parse(x, dpi, cell_px) }
121
+ instance_variable_set p_str, arr
122
+ else
123
+ instance_variable_set p_str, Squib::Args::UnitConversion.parse(p_val, dpi, cell_px)
124
+ end
125
+ end
126
+ self
125
127
  end
128
+
126
129
  end
@@ -1,55 +1,59 @@
1
1
  require_relative 'arg_loader'
2
+ require_relative 'xywh_shorthands'
2
3
 
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class Box
8
- include ArgLoader
9
-
10
- def initialize(deck = nil, dsl_method_defaults = {})
11
- @deck = deck
12
- @dsl_method_defaults = dsl_method_defaults
13
- end
14
-
15
- def self.parameters
16
- { x: 0, y: 0,
17
- width: :deck, height: :deck,
18
- radius: nil, x_radius: 0, y_radius: 0
19
- }
20
- end
21
-
22
- def self.expanding_parameters
23
- parameters.keys # all of them
24
- end
25
-
26
- def self.params_with_units
27
- parameters.keys # all of them
28
- end
29
-
30
- def validate_width(arg, _i)
31
- return arg if @deck.nil?
32
- return @deck.width if arg == :deck
33
- arg
34
- end
35
-
36
- def validate_height(arg, _i)
37
- return arg if @deck.nil?
38
- return @deck.height if arg == :deck
39
- arg
40
- end
41
-
42
- def validate_x_radius(arg, i)
43
- return radius[i] unless radius[i].nil?
44
- arg
45
- end
46
-
47
- def validate_y_radius(arg, i)
48
- return radius[i] unless radius[i].nil?
49
- arg
50
- end
4
+ module Squib::Args
51
5
 
6
+ module_function def extract_box(opts, deck, dsl_method_defaults = {})
7
+ Box.new(deck, dsl_method_defaults).extract!(opts, deck)
8
+ end
9
+
10
+ class Box
11
+ include ArgLoader
12
+ include XYWHShorthands
13
+
14
+ def initialize(deck = nil, dsl_method_defaults = {})
15
+ @deck = deck
16
+ @dsl_method_defaults = dsl_method_defaults
17
+ end
18
+
19
+ def self.parameters
20
+ { x: 0, y: 0,
21
+ width: :deck, height: :deck,
22
+ radius: nil, x_radius: 0, y_radius: 0
23
+ }
24
+ end
25
+
26
+ def self.expanding_parameters
27
+ parameters.keys # all of them
28
+ end
29
+
30
+ def self.params_with_units
31
+ parameters.keys # all of them
52
32
  end
53
33
 
34
+ def validate_x(arg, i) apply_shorthands(arg, @deck, axis: :x) end
35
+ def validate_y(arg,_i) apply_shorthands(arg, @deck, axis: :y) end
36
+
37
+ def validate_width(arg, _i)
38
+ return arg if @deck.nil?
39
+ apply_shorthands(arg, @deck, axis: :x)
40
+ end
41
+
42
+ def validate_height(arg, _i)
43
+ return arg if @deck.nil?
44
+ apply_shorthands(arg, @deck, axis: :y)
45
+ end
46
+
47
+ def validate_x_radius(arg, i)
48
+ return radius[i] unless radius[i].nil?
49
+ arg
50
+ end
51
+
52
+ def validate_y_radius(arg, i)
53
+ return radius[i] unless radius[i].nil?
54
+ arg
55
+ end
56
+
54
57
  end
58
+
55
59
  end