bread-basket 0.0.0 → 0.0.1

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +18 -0
  4. data/.travis.yml +4 -1
  5. data/Gemfile +1 -1
  6. data/Guardfile +7 -2
  7. data/README.md +28 -17
  8. data/Rakefile +13 -6
  9. data/bin/bread-basket +14 -0
  10. data/bread-basket.gemspec +29 -24
  11. data/lib/bread/basket.rb +12 -6
  12. data/lib/bread/basket/cli.rb +10 -0
  13. data/lib/bread/basket/poster.rb +38 -0
  14. data/lib/bread/basket/poster/block_code_handler.rb +50 -0
  15. data/lib/bread/basket/poster/block_renderer.rb +14 -0
  16. data/lib/bread/basket/poster/box.rb +119 -0
  17. data/lib/bread/basket/poster/box_checker.rb +60 -0
  18. data/lib/bread/basket/poster/columns.rb +90 -0
  19. data/lib/bread/basket/poster/css_reader.rb +130 -0
  20. data/lib/bread/basket/poster/dimensions_helper.rb +123 -0
  21. data/lib/bread/basket/poster/header_callback.rb +29 -0
  22. data/lib/bread/basket/poster/header_maker.rb +74 -0
  23. data/lib/bread/basket/poster/image_box.rb +93 -0
  24. data/lib/bread/basket/poster/layout.rb +108 -0
  25. data/lib/bread/basket/poster/pdf_builder.rb +113 -0
  26. data/lib/bread/basket/poster/poster_maker.rb +55 -0
  27. data/lib/bread/basket/poster/prawn_patches/column_box.rb +17 -0
  28. data/lib/bread/basket/poster/text_renderer.rb +89 -0
  29. data/lib/bread/basket/poster/units_helper.rb +39 -0
  30. data/lib/bread/basket/version.rb +1 -1
  31. data/samples/block_sample.css +86 -0
  32. data/samples/flow_sample.css +68 -0
  33. data/samples/ipsum.jpg +0 -0
  34. data/samples/lorem.jpg +0 -0
  35. data/samples/lorem_block.md +86 -0
  36. data/samples/lorem_flow.md +58 -0
  37. data/samples/lorem_flow.pdf +3834 -6
  38. data/samples/sample.md +59 -0
  39. data/samples/simple.css +19 -0
  40. data/samples/simple.md +3 -0
  41. data/samples/ucair_logo.png +0 -0
  42. data/spec/cli_spec.rb +13 -0
  43. data/spec/poster/block_code_handler_spec.rb +47 -0
  44. data/spec/poster/box_spec.rb +114 -0
  45. data/spec/poster/columns_spec.rb +64 -0
  46. data/spec/poster/css_reader_spec.rb +115 -0
  47. data/spec/poster/header_maker_spec.rb +49 -0
  48. data/spec/poster/image_box_spec.rb +69 -0
  49. data/spec/poster/layout_spec.rb +75 -0
  50. data/spec/poster/pdf_builder_spec.rb +60 -0
  51. data/spec/poster/poster_maker_spec.rb +15 -0
  52. data/spec/poster/test_files/bad_file.md +1 -0
  53. data/spec/poster/test_files/basic_block.css +14 -0
  54. data/spec/poster/test_files/basic_flow.css +31 -0
  55. data/spec/poster/test_files/block_code_test.css +13 -0
  56. data/spec/poster/test_files/builder.css +39 -0
  57. data/spec/poster/test_files/circular.css +39 -0
  58. data/spec/poster/test_files/dragon.png +0 -0
  59. data/spec/poster/test_files/fitted_image.css +39 -0
  60. data/spec/poster/test_files/good_file.md +5 -0
  61. data/spec/poster/test_files/good_file.pdf +0 -0
  62. data/spec/poster/test_files/header_test.css +22 -0
  63. data/spec/poster/test_files/nearly_empty.css +10 -0
  64. data/spec/poster/test_files/self_referential.css +108 -0
  65. data/spec/poster/test_files/ucair_logo.png +0 -0
  66. data/spec/poster/text_renderer_spec.rb +54 -0
  67. data/spec/poster/units_helper_spec.rb +36 -0
  68. data/spec/spec_helper.rb +6 -0
  69. metadata +212 -34
  70. data/bread-basket-0.0.1.gem +0 -0
  71. data/spec/basket_spec.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e88de24214b514b997f49898747732ceacc0a73
4
- data.tar.gz: 50c00bbc435f9797d45079dfb4740c1588f421d4
3
+ metadata.gz: 9cd2a8c7a51afc5eccbd1e627a982d10e59c1501
4
+ data.tar.gz: 4352f64d75add2341aafd3c9bc06f45bd475b4bf
5
5
  SHA512:
6
- metadata.gz: 444d8e8ec75f35a219cb09fe80da4b4abc8938ab358f7ace7e12b89d4b20388bd6ec6ab0d1b4fed20916eae3f1f019779c3f08766c19dbde0d57bf0e22cafccd
7
- data.tar.gz: 911ccad5a2c93f460a7ef50d0274a03afbbf7563cf25963838776edebae631ee5d3d9c656fb376991ce2565518e11ecc08982f9e2b3490a98d322117604e67e2
6
+ metadata.gz: d8c4cc7727a2a881a5e5a13b3be478a8d8628b2d065c6fd85367f23a684831e6decedd401422760d6d592a8eb94e5649e1b5fe33a62aab95d1e821f7814510b6
7
+ data.tar.gz: 92024548da731c38005e6d9ec119e30604b3a369756e4c347c61c9ed9d75e49931894f6c87ab470c119a928bab4f1ba653f6bfb7959c28bf06e4ab59f1cce361
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format progress
3
+ --order random
4
+ --require spec_helper
@@ -0,0 +1,18 @@
1
+ # This cop checks for top-level documentation of classes and modules.
2
+ Style/Documentation:
3
+ Enabled: false
4
+
5
+ # This cop checks for snake_case ruby file names.
6
+ # It is off because it triggers on ruby shebang.
7
+ Style/FileName:
8
+ Enabled: false
9
+
10
+ # This cop wisely checks for eval, but I use it carefully so
11
+ # it'll have to be silent
12
+ Lint/Eval:
13
+ Enabled: false
14
+
15
+ # My namespace puts methods 5 indents in 80->90
16
+ # many methods add at least 1 more indent 90->92
17
+ Metrics/LineLength:
18
+ Max: 92
@@ -2,9 +2,12 @@ language: ruby
2
2
  cache: bundler
3
3
 
4
4
  rvm:
5
- - jruby
6
5
  - 2.0.0
7
6
 
7
+ # Not sure why I need this!
8
+ before_install:
9
+ - 'gem install bundler'
10
+
8
11
  script: 'bundle exec rake'
9
12
 
10
13
  notifications:
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in bread-basket.gemspec
3
+ # Gem's dependencies are specified in bread-basket.gemspec
4
4
  gemspec
data/Guardfile CHANGED
@@ -1,11 +1,16 @@
1
1
  guard :rspec, cmd: 'bundle exec rspec' do
2
2
  # watch /lib/ files
3
- watch(%r{^lib/(.+).rb$}) do |m|
3
+ watch(/^lib\/(.+).rb$/) do |m|
4
4
  "spec/#{m[1]}_spec.rb"
5
5
  end
6
6
 
7
7
  # watch /spec/ files
8
- watch(%r{^spec/(.+).rb$}) do |m|
8
+ watch(/^spec\/(.+).rb$/) do |m|
9
9
  "spec/#{m[1]}.rb"
10
10
  end
11
11
  end
12
+
13
+ guard :rubocop do
14
+ watch(/.+\.rb$/)
15
+ watch(/(?:.+\/)?\.rubocop\.yml$/) { |m| File.dirname(m[0]) }
16
+ end
data/README.md CHANGED
@@ -1,36 +1,47 @@
1
1
  # Basket
2
+ [![Build Status](https://travis-ci.org/bread/bread-basket.svg?branch=master)](https://travis-ci.org/bread/bread-basket)
3
+ [![Coverage Status](https://coveralls.io/repos/bread/bread-basket/badge.svg?branch=master)](https://coveralls.io/r/bread/bread-basket?branch=master)
2
4
 
3
- Basket is a tool for publishing scientific findings. It's the last piece of the :bread: framework for scientific computing.
5
+ Basket is a tool for publishing scientific findings.
6
+ It's the last piece of the :bread: framework for scientific computing.
7
+ But it's the first thing I've tried to build in that framework.
4
8
 
5
- For now it just makes scientific posters. In the future thought it should help make figures, presentations, and maybe even full journal articles.
9
+ When the `Poster` module is finished it will make scientific posters.
10
+ In the future however, `bread-basket` should help make
11
+ figures, presentations, and maybe even full journal articles.
6
12
 
7
- ## Installation
13
+ ## Installation and Usage
8
14
 
9
- Add this line to your application's Gemfile:
15
+ Since :bread: hasn't been built (at all) yet, this little piece of the framework
16
+ is pretty lonely. So for now it's just a command-line utility
17
+ for making scientific posters. To use it, first get it into your Ruby environment with
10
18
 
11
- ```ruby
12
- gem 'bread-basket'
13
- ```
14
-
15
- And then execute:
19
+ $ gem install bread-basket
16
20
 
17
- $ bundle
21
+ (If you're brand new to Ruby and not so sure about the above line, I plan to put
22
+ an introduction to Ruby for scientists on the bread homepage. So just sit tight
23
+ until I get that built.)
18
24
 
19
- Or install it yourself as:
25
+ Once that's installed you should be able to convert a suitable markdown file
26
+ (with your poster's content) and stylesheet into a nice pdf like so
20
27
 
21
- $ gem install bread-basket
28
+ $ bread-basket poster my-poster.md
22
29
 
23
- ## Usage
30
+ and it will produce a pdf that you can take to the printers!
24
31
 
25
- The only tool in the Bread Basket is Posterize. You should call it from the command line with the path to your poster markdown file like so
32
+ For more information on how to write the markdown file for your poster
33
+ check out the example below, or email me. In the future a website will
34
+ provide some good documentation.
26
35
 
27
- $ posterize my-poster.md
36
+ ## Example
28
37
 
29
- and it will produce a pdf that you can take to the printers. For more information on how to write the markdown file for you poster check out the website (doesn't exist yet).
38
+ The samples folder contains an example poster `lorem_flow.md` along with the pdf
39
+ this software creates. Right now this is the only sample that works so go check it
40
+ out.
30
41
 
31
42
  ## Contributing
32
43
 
33
- 1. Fork it ( https://github.com/[my-github-username]/bread-basket/fork )
44
+ 1. Fork it ( https://github.com/bread/bread-basket/fork )
34
45
  2. Create your feature branch (`git checkout -b my-new-feature`)
35
46
  3. Commit your changes (`git commit -am 'Add some feature'`)
36
47
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1,10 +1,17 @@
1
1
  require 'rspec/core/rake_task'
2
- require "bundler/gem_tasks"
2
+ require 'bundler/gem_tasks'
3
+ require 'rubocop/rake_task'
3
4
 
4
5
  # Default directory to look in is `/specs`
5
- # Run with `rake spec`
6
- RSpec::Core::RakeTask.new(:spec) do |task|
7
- task.rspec_opts = ['--color', '--format', 'nested']
8
- end
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
9
9
 
10
- task :default => :spec
10
+ desc 'Run RuboCop on the lib directory'
11
+ RuboCop::RakeTask.new(:rubocop) do |task|
12
+ task.patterns = ['lib/bread/**/*.rb']
13
+ # only show the files with failures
14
+ task.formatters = ['files']
15
+ # don't abort rake on failure
16
+ task.fail_on_error = false
17
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Avoid running bundle exec by running this first instead!
4
+ lib_directory = File.expand_path('../../lib', __FILE__)
5
+ $LOAD_PATH << lib_directory
6
+
7
+ if File.exist?('Gemfile')
8
+ require 'bundler/setup'
9
+ Bundler.require
10
+ end
11
+
12
+ require 'bread/basket'
13
+
14
+ Bread::Basket::Cli.start(ARGV)
@@ -4,32 +4,37 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'bread/basket/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "bread-basket"
7
+ spec.name = 'bread-basket'
8
8
  spec.version = Bread::Basket::VERSION
9
- spec.authors = ["KC Erb"]
10
- spec.email = ["iamkcerb@gmail.com"]
11
- spec.summary = "The publication tool for bread"
12
- spec.description =
13
- 'Basket is a tool for publishing scientific findings. It\'s the last piece of ' +
14
- 'the :bread: framework for scientific computing.\n\nFor now it just makes' +
15
- 'scientific posters. In the future thought it should help make figures,' +
16
- ' presentations, and maybe even full journal articles.'
17
- spec.homepage = "https://github.com/bread/bread-basket"
18
- spec.license = "MIT"
9
+ spec.authors = ['KC Erb']
10
+ spec.email = ['iamkcerb@gmail.com']
11
+ spec.summary = 'The go-to publication tool for bread'
12
+ spec.description = 'bread-basket is still under development. This release ' \
13
+ 'contains only bare-bones functionality'
14
+ spec.homepage = 'https://github.com/bread/bread-basket'
15
+ spec.license = 'MIT'
19
16
 
20
17
  spec.files = `git ls-files -z`.split("\x0")
21
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
- spec.require_paths = ["lib"]
18
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
20
+ spec.require_paths = ['lib']
24
21
 
25
- spec.add_development_dependency "bundler", "~> 1.7"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "rspec", "~> 3.2"
28
- spec.add_development_dependency "rspec-nc", "~> 0"
29
- spec.add_development_dependency "guard", "~> 2.12"
30
- spec.add_development_dependency "guard-rspec", "~> 4.0"
31
- spec.add_development_dependency "pry", "~> 0.10"
32
- spec.add_development_dependency "pry-remote", "~> 0.1"
33
- spec.add_development_dependency "pry-nav", "~> 0.2"
34
- spec.add_development_dependency "coveralls", "~> 0.7"
22
+ spec.add_development_dependency 'bundler', '~> 1.9'
23
+ spec.add_development_dependency 'coveralls', '~> 0.7'
24
+ spec.add_development_dependency 'rake', '~> 10.4'
25
+ spec.add_development_dependency 'guard', '~> 2.12'
26
+ spec.add_development_dependency 'guard-rspec', '~> 4.5'
27
+ spec.add_development_dependency 'guard-rubocop', '~> 1.2'
28
+ spec.add_development_dependency 'pry', '~> 0.10'
29
+ spec.add_development_dependency 'pry-nav', '~> 0.2'
30
+ spec.add_development_dependency 'pry-remote', '~> 0.1'
31
+ spec.add_development_dependency 'rspec', '~> 3.2'
32
+ spec.add_development_dependency 'rspec-its', '~> 1.2'
33
+ spec.add_development_dependency 'rspec-nc', '~> 0'
34
+
35
+ spec.add_dependency 'css_parser', '~> 1.3'
36
+ spec.add_dependency 'fastimage', '~> 1.6'
37
+ spec.add_dependency 'prawn', '~> 2.0'
38
+ spec.add_dependency 'redcarpet', '~> 3.2'
39
+ spec.add_dependency 'thor', '~> 0.19'
35
40
  end
@@ -1,7 +1,13 @@
1
- require "bread/basket/version"
1
+ # gems
2
+ require 'yaml'
3
+ require 'thor'
4
+ require 'css_parser'
5
+ require 'prawn'
6
+ require 'prawn/measurement_extensions'
7
+ require 'fastimage'
8
+ require 'redcarpet'
2
9
 
3
- module Bread
4
- module Basket
5
- # Your code goes here...
6
- end
7
- end
10
+ # local
11
+ require 'bread/basket/version'
12
+ require 'bread/basket/cli'
13
+ require 'bread/basket/poster'
@@ -0,0 +1,10 @@
1
+ module Bread
2
+ module Basket
3
+ class Cli < Thor
4
+ desc 'poster FILENAME', 'Creates a scientific poster from FILENAME'
5
+ def poster(file)
6
+ Bread::Basket::Poster::PosterMaker.new(file)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,38 @@
1
+ require 'bread/basket/poster/prawn_patches/column_box'
2
+ require 'bread/basket/poster/header_callback'
3
+ require 'bread/basket/poster/header_maker'
4
+ require 'bread/basket/poster/text_renderer'
5
+ require 'bread/basket/poster/block_renderer'
6
+ require 'bread/basket/poster/poster_maker'
7
+ require 'bread/basket/poster/layout'
8
+ require 'bread/basket/poster/box_checker'
9
+ require 'bread/basket/poster/units_helper'
10
+ require 'bread/basket/poster/dimensions_helper'
11
+ require 'bread/basket/poster/box'
12
+ require 'bread/basket/poster/image_box'
13
+ require 'bread/basket/poster/columns'
14
+ require 'bread/basket/poster/css_reader'
15
+ require 'bread/basket/poster/pdf_builder'
16
+ require 'bread/basket/poster/block_code_handler'
17
+
18
+ module Bread
19
+ module Basket
20
+ module Poster
21
+ TEXT_RENDERER_OPTS = { fenced_code_blocks: true,
22
+ disable_indented_code_blocks: true,
23
+ underline: true,
24
+ highlight: true,
25
+ superscript: true,
26
+ tables: true }
27
+ class << self
28
+ attr_accessor :dir_path, :layout, :pdf, :current_styles, :body
29
+ end
30
+
31
+ # Default dir path, since in some specs this doesn't get set
32
+ # this is a code smell and is on the to do list.
33
+ dirname = File.dirname(__FILE__)
34
+ Poster.dir_path = File.expand_path('../../../', dirname) + '/spec/poster/test_files'
35
+ Poster.current_styles = {}
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,50 @@
1
+ module Bread
2
+ module Basket
3
+ module Poster
4
+ class BlockCodeHandler
5
+ attr_reader :pdf, :layout, :text_renderer
6
+
7
+ def initialize(pdf, layout, first_line, content)
8
+ @pdf = pdf
9
+ @layout = layout
10
+ @text_renderer = Redcarpet::Markdown.new(TextRenderer, TEXT_RENDERER_OPTS)
11
+ sort_input(first_line, content)
12
+ end
13
+
14
+ def sort_input(first_line, content)
15
+ case first_line
16
+ when /\A.*\.(jpg|jpeg|png)\Z/
17
+ create_image(first_line, content)
18
+ else
19
+ puts "Warning: Couldn't figure out what to do with #{content} block.\n"
20
+ end
21
+ end
22
+
23
+ # TODO: Get a lot of these values from the CSS
24
+ def create_image(image_src, caption)
25
+ image_path = Bread::Basket::Poster.dir_path + '/' + image_src
26
+ @columns_width = layout.columns[0].width
27
+ pdf.image image_path, width: @columns_width, position: :center
28
+ pdf.move_down 15
29
+ draw_caption(caption)
30
+ end
31
+
32
+ def draw_caption(caption)
33
+ top_left = [pdf.bounds.left + 20, pdf.cursor]
34
+ pdf.bounding_box(top_left, width: @columns_width - 40) do
35
+ # spin up a new renderer since this is called within one and Redcarpet
36
+ # doesn't allow this: https://github.com/vmg/redcarpet/issues/318
37
+ caption_content caption
38
+ end
39
+ end
40
+
41
+ def caption_content(caption)
42
+ pdf.stroke_bounds
43
+ pdf.move_down 15
44
+ text_renderer.render(caption)
45
+ pdf.move_down 36
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ module Bread
2
+ module Basket
3
+ module Poster
4
+ class BlockRenderer < TextRenderer
5
+ attr_reader :pdf, :layout
6
+
7
+ # create pdf bounding box
8
+ def header(_text, _header_level)
9
+ # needs to be scss aware
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,119 @@
1
+ module Bread
2
+ module Basket
3
+ module Poster
4
+ class Box
5
+ include UnitsHelper
6
+ # Box does most of the heavy lifting of the self-referential css
7
+ # so it's a little confusing. It passes dimensions off to the dimensions
8
+ # helper and holds the methods for setting dimensions as either pending
9
+ # or determined and how to resolve those issues.
10
+ attr_reader :selector_name, :method_name, :layout, :specs,
11
+ :pending, :unfinished, :styles
12
+ attr_accessor :top, :left, :width, :height, :bottom, :right, :stretchy,
13
+ :content
14
+
15
+ def initialize(name, layout, specs = {})
16
+ fetch_names(name)
17
+ @layout = layout
18
+ @specs = specs
19
+ @styles = specs
20
+ @pending = []
21
+ @unfinished = []
22
+
23
+ setup_dimensions
24
+ layout.image_boxes << method_name if self.is_a? ImageBox
25
+ layout.boxes << selector_name
26
+ end
27
+
28
+ def fetch_names(name)
29
+ @selector_name = name
30
+ @method_name = name.sub('.', '').gsub('-', '_')
31
+ end
32
+
33
+ def setup_dimensions
34
+ DimensionsHelper.new(self, layout, specs)
35
+ layout.pending << selector_name unless pending.empty?
36
+ end
37
+
38
+ def try_to_resolve
39
+ pending.each do |dimension|
40
+ hash = send dimension
41
+ try_dimension hash
42
+ resolve_dimension(dimension, hash) if ready_to_resolve? hash
43
+ end
44
+ end
45
+
46
+ def try_dimension(dimensions_hash)
47
+ dimensions_hash[:pending].delete_if do |dimension_key, index|
48
+ value = layout.determined[dimension_key]
49
+ if value && value != :stretchy
50
+ command_arr = dimensions_hash[:command]
51
+ command_arr[index] = value
52
+ end
53
+ end
54
+ end
55
+
56
+ def resolve_dimension(dimension, hash)
57
+ command_string = hash[:command].join(' ')
58
+ value = eval command_string
59
+ instance_variable_set "@#{dimension}", value
60
+ pending.delete dimension
61
+ add_to_determined dimension, value
62
+ resolve_box if pending.empty?
63
+ end
64
+
65
+ def ready_to_resolve?(hash)
66
+ hash[:pending].empty? && safe?(hash[:command])
67
+ end
68
+
69
+ def safe?(command_array)
70
+ command_array.all? do |elem|
71
+ (elem.is_a? Numeric) || ([:+, :-, :/, :*, '(', ')'].include?(elem))
72
+ end
73
+ end
74
+
75
+ def add_to_determined(dimension_name, value)
76
+ name = method_name + '.' + dimension_name
77
+ instance_variable_set "@#{dimension_name}", value
78
+ layout.determined[name] = value
79
+ end
80
+
81
+ def resolve_box
82
+ layout.pending.delete selector_name
83
+ unfinished.each { |dimension| determine_missing dimension }
84
+ end
85
+ # Rubocop hates determine_missing
86
+ # rubocop:disable all
87
+ def determine_missing(missing_dimension)
88
+ value = case missing_dimension
89
+ when 'left'
90
+ right - width
91
+ when 'right'
92
+ left + width
93
+ when 'width'
94
+ right - left
95
+ when 'top'
96
+ bottom + height
97
+ when 'height'
98
+ top - bottom
99
+ when 'bottom'
100
+ top - height
101
+ end
102
+ add_to_determined missing_dimension, value
103
+ end
104
+ # rubocop:enable all
105
+ def inspect
106
+ str = ''
107
+ %w(top left width height bottom right).each do |dim|
108
+ str << "#{dim}: #{send(dim)}; "
109
+ end
110
+ str.strip
111
+ end
112
+
113
+ def stretchy?
114
+ !stretchy.nil?
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end