geo_pattern 1.3.2 → 1.4.0
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/.rubocop.yml +58 -0
- data/.simplecov +25 -0
- data/.travis.yml +12 -0
- data/Gemfile +3 -1
- data/README.md +125 -23
- data/Rakefile +72 -9
- data/fixtures/generated_patterns/chevrons.svg +1 -0
- data/fixtures/generated_patterns/concentric_circles.svg +1 -0
- data/fixtures/generated_patterns/diamonds.svg +1 -0
- data/fixtures/generated_patterns/diamonds_with_base_color.svg +1 -0
- data/fixtures/generated_patterns/diamonds_with_color.svg +1 -0
- data/fixtures/generated_patterns/hexagons.svg +1 -0
- data/fixtures/generated_patterns/mosaic_squares.svg +1 -0
- data/fixtures/generated_patterns/nested_squares.svg +1 -0
- data/fixtures/generated_patterns/octagons.svg +1 -0
- data/fixtures/generated_patterns/overlapping_circles.svg +1 -0
- data/fixtures/generated_patterns/overlapping_rings.svg +1 -0
- data/fixtures/generated_patterns/plaid.svg +1 -0
- data/fixtures/generated_patterns/plus_signs.svg +1 -0
- data/fixtures/generated_patterns/sine_waves.svg +1 -0
- data/fixtures/generated_patterns/squares.svg +1 -0
- data/fixtures/generated_patterns/tessellation.svg +1 -0
- data/fixtures/generated_patterns/triangles.svg +1 -0
- data/fixtures/generated_patterns/xes.svg +1 -0
- data/geo_pattern.gemspec +8 -2
- data/lib/geo_pattern.rb +42 -20
- data/lib/geo_pattern/background.rb +25 -0
- data/lib/geo_pattern/background_generators/solid_generator.rb +52 -0
- data/lib/geo_pattern/color.rb +25 -0
- data/lib/geo_pattern/color_generators/base_color_generator.rb +55 -0
- data/lib/geo_pattern/color_generators/simple_generator.rb +27 -0
- data/lib/geo_pattern/color_preset.rb +26 -0
- data/lib/geo_pattern/errors.rb +7 -0
- data/lib/geo_pattern/geo_pattern_task.rb +59 -0
- data/lib/geo_pattern/helpers.rb +47 -0
- data/lib/geo_pattern/pattern.rb +84 -0
- data/lib/geo_pattern/pattern_generator.rb +33 -82
- data/lib/geo_pattern/pattern_helpers.rb +31 -2
- data/lib/geo_pattern/pattern_preset.rb +23 -0
- data/lib/geo_pattern/pattern_sieve.rb +36 -0
- data/lib/geo_pattern/pattern_store.rb +63 -0
- data/lib/geo_pattern/pattern_validator.rb +27 -0
- data/lib/geo_pattern/rake_task.rb +109 -0
- data/lib/geo_pattern/roles/comparable_metadata.rb +35 -0
- data/lib/geo_pattern/roles/named_generator.rb +13 -0
- data/lib/geo_pattern/seed.rb +21 -0
- data/lib/geo_pattern/structure.rb +25 -0
- data/lib/geo_pattern/structure_generators/base_generator.rb +85 -0
- data/lib/geo_pattern/structure_generators/chevrons_generator.rb +55 -0
- data/lib/geo_pattern/structure_generators/concentric_circles_generator.rb +56 -0
- data/lib/geo_pattern/structure_generators/diamonds_generator.rb +66 -0
- data/lib/geo_pattern/structure_generators/hexagons_generator.rb +67 -0
- data/lib/geo_pattern/structure_generators/mosaic_squares_generator.rb +85 -0
- data/lib/geo_pattern/structure_generators/nested_squares_generator.rb +60 -0
- data/lib/geo_pattern/structure_generators/octagons_generator.rb +44 -0
- data/lib/geo_pattern/structure_generators/overlapping_circles_generator.rb +55 -0
- data/lib/geo_pattern/structure_generators/overlapping_rings_generator.rb +55 -0
- data/lib/geo_pattern/structure_generators/plaid_generator.rb +55 -0
- data/lib/geo_pattern/structure_generators/plus_signs_generator.rb +62 -0
- data/lib/geo_pattern/structure_generators/sine_waves_generator.rb +43 -0
- data/lib/geo_pattern/structure_generators/squares_generator.rb +36 -0
- data/lib/geo_pattern/structure_generators/tessellation_generator.rb +103 -0
- data/lib/geo_pattern/structure_generators/triangles_generator.rb +61 -0
- data/lib/geo_pattern/structure_generators/xes_generator.rb +67 -0
- data/lib/geo_pattern/svg_image.rb +101 -0
- data/lib/geo_pattern/version.rb +1 -1
- data/script/bootstrap +30 -0
- data/script/console +8 -0
- data/script/test +21 -0
- data/spec/background_generators/solid_generator_spec.rb +50 -0
- data/spec/background_spec.rb +25 -0
- data/spec/color_generators/base_color_generator_spec.rb +31 -0
- data/spec/color_generators/simple_generator_spec.rb +12 -0
- data/spec/color_preset_spec.rb +53 -0
- data/spec/color_spec.rb +15 -0
- data/spec/geo_pattern_spec.rb +95 -24
- data/spec/helpers_spec.rb +65 -0
- data/spec/pattern_preset_spec.rb +41 -0
- data/spec/pattern_sieve_spec.rb +66 -0
- data/spec/pattern_spec.rb +72 -0
- data/spec/pattern_store_spec.rb +47 -0
- data/spec/pattern_validator_spec.rb +28 -0
- data/spec/seed_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -6
- data/spec/structure_generators/chevrons_generator_spec.rb +5 -0
- data/spec/structure_generators/concentric_circles_generator_spec.rb +5 -0
- data/spec/structure_generators/diamonds_generator_spec.rb +5 -0
- data/spec/structure_generators/hexagons_generator_spec.rb +5 -0
- data/spec/structure_generators/mosaic_squares_generator_spec.rb +5 -0
- data/spec/structure_generators/nested_squares_generator_spec.rb +5 -0
- data/spec/structure_generators/octagons_generator_spec.rb +5 -0
- data/spec/structure_generators/overlapping_circles_generator_spec.rb +5 -0
- data/spec/structure_generators/overlapping_rings_generator_spec.rb +5 -0
- data/spec/structure_generators/plaid_generator_spec.rb +5 -0
- data/spec/structure_generators/plus_signs_generator_spec.rb +5 -0
- data/spec/structure_generators/sine_waves_generator_spec.rb +5 -0
- data/spec/structure_generators/squares_generator_spec.rb +5 -0
- data/spec/structure_generators/tessellation_generator_spec.rb +5 -0
- data/spec/structure_generators/triangles_generator_spec.rb +5 -0
- data/spec/structure_generators/xes_generator_spec.rb +5 -0
- data/spec/structure_spec.rb +38 -0
- data/spec/support/helpers/fixtures.rb +12 -0
- data/spec/support/kernel.rb +40 -0
- data/spec/support/matchers/image.rb +17 -0
- data/spec/support/matchers/name.rb +15 -0
- data/spec/support/rspec.rb +1 -1
- data/spec/support/shared_examples/generator.rb +46 -0
- data/spec/support/shared_examples/pattern.rb +31 -0
- data/spec/support/shared_examples/pattern_name.rb +7 -0
- data/spec/support/shared_examples/structure.rb +48 -0
- data/spec/svg_spec.rb +3 -3
- metadata +141 -25
- data/lib/geo_pattern/pattern/base_pattern.rb +0 -47
- data/lib/geo_pattern/pattern/chevron_pattern.rb +0 -45
- data/lib/geo_pattern/pattern/concentric_circles_pattern.rb +0 -47
- data/lib/geo_pattern/pattern/diamond_pattern.rb +0 -56
- data/lib/geo_pattern/pattern/hexagon_pattern.rb +0 -57
- data/lib/geo_pattern/pattern/mosaic_squares_pattern.rb +0 -76
- data/lib/geo_pattern/pattern/nested_squares_pattern.rb +0 -51
- data/lib/geo_pattern/pattern/octagon_pattern.rb +0 -35
- data/lib/geo_pattern/pattern/overlapping_circles_pattern.rb +0 -46
- data/lib/geo_pattern/pattern/overlapping_rings_pattern.rb +0 -46
- data/lib/geo_pattern/pattern/plaid_pattern.rb +0 -49
- data/lib/geo_pattern/pattern/plus_sign_pattern.rb +0 -53
- data/lib/geo_pattern/pattern/sine_wave_pattern.rb +0 -36
- data/lib/geo_pattern/pattern/square_pattern.rb +0 -27
- data/lib/geo_pattern/pattern/tessellation_pattern.rb +0 -93
- data/lib/geo_pattern/pattern/triangle_pattern.rb +0 -51
- data/lib/geo_pattern/pattern/xes_pattern.rb +0 -58
- data/lib/geo_pattern/svg.rb +0 -77
- data/spec/support/helpers.rb +0 -34
@@ -0,0 +1,84 @@
|
|
1
|
+
module GeoPattern
|
2
|
+
class Pattern
|
3
|
+
private
|
4
|
+
|
5
|
+
attr_reader :svg_image
|
6
|
+
|
7
|
+
public
|
8
|
+
|
9
|
+
attr_accessor :background, :structure, :height, :width
|
10
|
+
|
11
|
+
def initialize(svg_image = SvgImage.new)
|
12
|
+
@svg_image = svg_image
|
13
|
+
end
|
14
|
+
|
15
|
+
# Check if string is included in pattern
|
16
|
+
#
|
17
|
+
# @param [String] string
|
18
|
+
# The checked string
|
19
|
+
def include?(string)
|
20
|
+
image.include?(string)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Generate things for the pattern
|
24
|
+
#
|
25
|
+
# @param [#generate) generator
|
26
|
+
# The generator which should do things with this pattern - e.g. adding
|
27
|
+
# background or a structure
|
28
|
+
def generate_me(generator)
|
29
|
+
generator.generate self
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convert pattern to svg
|
33
|
+
def to_svg
|
34
|
+
image.to_s
|
35
|
+
end
|
36
|
+
alias_method :to_s, :to_svg
|
37
|
+
|
38
|
+
# Convert to base64
|
39
|
+
def to_base64
|
40
|
+
Base64.strict_encode64(to_svg)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Convert to data uri
|
44
|
+
def to_data_uri
|
45
|
+
"url(data:image/svg+xml;base64,#{to_base64});"
|
46
|
+
end
|
47
|
+
|
48
|
+
# @see #to_data_uri
|
49
|
+
# @deprecated
|
50
|
+
def uri_image
|
51
|
+
$stderr.puts 'Using "#uri_image" is deprecated as of 1.3.1. Please use "#to_data_uri" instead.'
|
52
|
+
|
53
|
+
to_data_uri
|
54
|
+
end
|
55
|
+
|
56
|
+
# @see #to_svg
|
57
|
+
# @deprecated
|
58
|
+
def svg_string
|
59
|
+
$stderr.puts 'Using "#svg_string" is deprecated as of 1.3.1. Please use "#to_svg" instead.'
|
60
|
+
|
61
|
+
to_svg
|
62
|
+
end
|
63
|
+
|
64
|
+
# @see #to_base64
|
65
|
+
# @deprecated
|
66
|
+
def base64_string
|
67
|
+
$stderr.puts 'Using "#base64_string" is deprecated as of 1.3.1. Please use "#to_base64" instead.'
|
68
|
+
|
69
|
+
to_base64
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def image
|
75
|
+
svg_image.height = height
|
76
|
+
svg_image.width = width
|
77
|
+
|
78
|
+
svg_image << background.image if background
|
79
|
+
svg_image << structure.image if structure
|
80
|
+
|
81
|
+
svg_image
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,101 +1,52 @@
|
|
1
1
|
module GeoPattern
|
2
2
|
class PatternGenerator
|
3
|
-
|
4
|
-
:base_color => '#933c3c'
|
5
|
-
}
|
3
|
+
private
|
6
4
|
|
7
|
-
|
8
|
-
'chevrons' => ChevronPattern,
|
9
|
-
'concentric_circles' => ConcentricCirclesPattern,
|
10
|
-
'diamonds' => DiamondPattern,
|
11
|
-
'hexagons' => HexagonPattern,
|
12
|
-
'mosaic_squares' => MosaicSquaresPattern,
|
13
|
-
'nested_squares' => NestedSquaresPattern,
|
14
|
-
'octagons' => OctagonPattern,
|
15
|
-
'overlapping_circles' => OverlappingCirclesPattern,
|
16
|
-
'overlapping_rings' => OverlappingRingsPattern,
|
17
|
-
'plaid' => PlaidPattern,
|
18
|
-
'plus_signs' => PlusSignPattern,
|
19
|
-
'sine_waves' => SineWavePattern,
|
20
|
-
'squares' => SquarePattern,
|
21
|
-
'tessellation' => TessellationPattern,
|
22
|
-
'triangles' => TrianglePattern,
|
23
|
-
'xes' => XesPattern,
|
24
|
-
}.freeze
|
5
|
+
attr_reader :background_generator, :structure_generator
|
25
6
|
|
26
|
-
|
27
|
-
FILL_COLOR_LIGHT = "#ddd"
|
28
|
-
STROKE_COLOR = "#000"
|
29
|
-
STROKE_OPACITY = 0.02
|
30
|
-
OPACITY_MIN = 0.02
|
31
|
-
OPACITY_MAX = 0.15
|
7
|
+
public
|
32
8
|
|
33
|
-
|
9
|
+
def initialize(string, generator: nil, patterns: nil, base_color: nil, color: nil)
|
10
|
+
$stderr.puts 'Using generator key is deprecated as of 1.3.1' if generator
|
34
11
|
|
35
|
-
|
36
|
-
@opts = DEFAULTS.merge(opts)
|
37
|
-
@hash = Digest::SHA1.hexdigest string
|
38
|
-
@svg = SVG.new
|
12
|
+
requested_patterns = (Array(generator) | Array(patterns)).flatten.compact
|
39
13
|
|
40
|
-
|
41
|
-
|
42
|
-
|
14
|
+
pattern_preset = PatternPreset.new(
|
15
|
+
fill_color_dark: '#222',
|
16
|
+
fill_color_light: '#ddd',
|
17
|
+
stroke_color: '#000',
|
18
|
+
stroke_opacity: 0.02,
|
19
|
+
opacity_min: 0.02,
|
20
|
+
opacity_max: 0.15
|
21
|
+
)
|
43
22
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
23
|
+
color_preset = ColorPreset.new(
|
24
|
+
base_color: '#933c3c'
|
25
|
+
)
|
26
|
+
color_preset.color = color if color
|
27
|
+
color_preset.base_color = base_color if base_color
|
48
28
|
|
49
|
-
|
50
|
-
Base64.strict_encode64(svg_string)
|
51
|
-
end
|
29
|
+
seed = Seed.new(string)
|
52
30
|
|
53
|
-
|
54
|
-
|
55
|
-
end
|
31
|
+
pattern_validator = PatternValidator.new
|
32
|
+
pattern_validator.validate(requested_patterns)
|
56
33
|
|
57
|
-
|
58
|
-
if opts[:color]
|
59
|
-
rgb = Color::RGB.from_html(opts[:color])
|
60
|
-
else
|
61
|
-
hue_offset = PatternHelpers.map(PatternHelpers.hex_val(hash, 14, 3), 0, 4095, 0, 359)
|
62
|
-
sat_offset = PatternHelpers.hex_val(hash, 17, 1)
|
63
|
-
base_color = Color::RGB.from_html(opts[:base_color]).to_hsl
|
64
|
-
base_color.hue = base_color.hue - hue_offset;
|
34
|
+
pattern_sieve = PatternSieve.new(requested_patterns, seed)
|
65
35
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
rgb = base_color.to_rgb
|
72
|
-
end
|
73
|
-
r = (rgb.r * 255).round
|
74
|
-
g = (rgb.g * 255).round
|
75
|
-
b = (rgb.b * 255).round
|
76
|
-
svg.rect(0, 0, "100%", "100%", {"fill" => "rgb(#{r}, #{g}, #{b})"})
|
36
|
+
@background_generator = BackgroundGenerators::SolidGenerator.new(seed, color_preset)
|
37
|
+
@structure_generator = begin
|
38
|
+
generator_klass = pattern_sieve.fetch
|
39
|
+
generator_klass.new(seed, pattern_preset)
|
40
|
+
end
|
77
41
|
end
|
78
42
|
|
79
|
-
def
|
80
|
-
|
81
|
-
if opts[:generator].is_a? String
|
82
|
-
generator = PATTERNS[opts[:generator]]
|
83
|
-
puts SVG.as_comment("String pattern references are deprecated as of 1.3.0")
|
84
|
-
elsif opts[:generator] < BasePattern
|
85
|
-
if PATTERNS.values.include? opts[:generator]
|
86
|
-
generator = opts[:generator]
|
87
|
-
else
|
88
|
-
abort("Error: the requested generator is invalid")
|
89
|
-
generator = nil
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
43
|
+
def generate
|
44
|
+
pattern = Pattern.new
|
93
45
|
|
94
|
-
|
46
|
+
pattern.generate_me background_generator
|
47
|
+
pattern.generate_me structure_generator
|
95
48
|
|
96
|
-
|
97
|
-
# and render the pattern to the svg object
|
98
|
-
generator.new(svg, hash).render_to_svg
|
49
|
+
pattern
|
99
50
|
end
|
100
51
|
end
|
101
52
|
end
|
@@ -1,17 +1,46 @@
|
|
1
1
|
module GeoPattern
|
2
2
|
module PatternHelpers
|
3
|
-
def
|
3
|
+
def hex_val(hash, index, length)
|
4
4
|
hash[index, length || 1].to_i(16)
|
5
5
|
end
|
6
6
|
|
7
7
|
# Ruby implementation of Processing's map function
|
8
8
|
# http://processing.org/reference/map_.html
|
9
|
-
def
|
9
|
+
def map(value, v_min, v_max, d_min, d_max) # v for value, d for desired
|
10
10
|
v_value = value.to_f # so it returns float
|
11
11
|
|
12
12
|
v_range = v_max - v_min
|
13
13
|
d_range = d_max - d_min
|
14
14
|
(v_value - v_min) * d_range / v_range + d_min
|
15
15
|
end
|
16
|
+
|
17
|
+
def html_to_rgb(color)
|
18
|
+
generate_rgb_string(::Color::RGB.from_html(color))
|
19
|
+
end
|
20
|
+
|
21
|
+
def html_to_rgb_for_string(seed, base_color)
|
22
|
+
hue_offset = map(seed.to_i(14, 3), 0, 4095, 0, 359)
|
23
|
+
sat_offset = seed.to_i(17, 1)
|
24
|
+
base_color = ::Color::RGB.from_html(base_color).to_hsl
|
25
|
+
base_color.hue = base_color.hue - hue_offset
|
26
|
+
|
27
|
+
if (sat_offset % 2 == 0)
|
28
|
+
base_color.saturation = base_color.saturation + sat_offset
|
29
|
+
else
|
30
|
+
base_color.saturation = base_color.saturation - sat_offset
|
31
|
+
end
|
32
|
+
|
33
|
+
generate_rgb_string(base_color.to_rgb)
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_rgb_string(rgb)
|
37
|
+
r = (rgb.r * 255).round
|
38
|
+
g = (rgb.g * 255).round
|
39
|
+
b = (rgb.b * 255).round
|
40
|
+
|
41
|
+
format('rgb(%d, %d, %d)', r, g, b)
|
42
|
+
end
|
43
|
+
|
44
|
+
module_function :hex_val, :map, :html_to_rgb, :html_to_rgb_for_string, :generate_rgb_string
|
16
45
|
end
|
17
46
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module GeoPattern
|
2
|
+
class PatternPreset
|
3
|
+
private
|
4
|
+
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
public
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
[:fill_color_dark, :fill_color_light, :stroke_color, :stroke_opacity, :opacity_min, :opacity_max].each do |m|
|
14
|
+
define_method m do
|
15
|
+
options[m]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(opts)
|
20
|
+
options.merge! opts
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module GeoPattern
|
2
|
+
class PatternSieve
|
3
|
+
private
|
4
|
+
|
5
|
+
attr_reader :pattern_store, :requested_patterns, :seed, :available_patterns, :index
|
6
|
+
|
7
|
+
public
|
8
|
+
|
9
|
+
def initialize(requested_patterns, seed, pattern_store = PatternStore.new)
|
10
|
+
@requested_patterns = requested_patterns
|
11
|
+
@seed = seed
|
12
|
+
@pattern_store = pattern_store
|
13
|
+
|
14
|
+
@available_patterns = determine_available_patterns
|
15
|
+
@index = determine_index
|
16
|
+
end
|
17
|
+
|
18
|
+
def fetch
|
19
|
+
available_patterns[index]
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def determine_index
|
25
|
+
[seed.to_i(20, 1), available_patterns.length - 1].min
|
26
|
+
end
|
27
|
+
|
28
|
+
def determine_available_patterns
|
29
|
+
patterns = Array(requested_patterns).compact
|
30
|
+
|
31
|
+
return pattern_store.all if patterns.empty?
|
32
|
+
|
33
|
+
patterns.map { |p| pattern_store[p] }.compact
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module GeoPattern
|
2
|
+
# rubocop:disable Style/ConstantName
|
3
|
+
ChevronPattern = :chevrons
|
4
|
+
ConcentricCirclesPattern = :concentric_circles
|
5
|
+
DiamondPattern = :diamonds
|
6
|
+
HexagonPattern = :hexagons
|
7
|
+
MosaicSquaresPattern = :mosaic_squares
|
8
|
+
NestedSquaresPattern = :nested_squares
|
9
|
+
OctagonPattern = :octagons
|
10
|
+
OverlappingCirclesPattern = :overlapping_circles
|
11
|
+
OverlappingRingsPattern = :overlapping_rings
|
12
|
+
PlaidPattern = :plaid
|
13
|
+
PlusSignPattern = :plus_signs
|
14
|
+
SineWavePattern = :sine_waves
|
15
|
+
SquarePattern = :squares
|
16
|
+
TessellationPattern = :tessellation
|
17
|
+
TrianglePattern = :triangles
|
18
|
+
XesPattern = :xes
|
19
|
+
# rubocop:enable Style/ConstantName
|
20
|
+
|
21
|
+
class PatternStore
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :store
|
25
|
+
|
26
|
+
public
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@store = {
|
30
|
+
chevrons: StructureGenerators::ChevronsGenerator,
|
31
|
+
concentric_circles: StructureGenerators::ConcentricCirclesGenerator,
|
32
|
+
diamonds: StructureGenerators::DiamondsGenerator,
|
33
|
+
hexagons: StructureGenerators::HexagonsGenerator,
|
34
|
+
mosaic_squares: StructureGenerators::MosaicSquaresGenerator,
|
35
|
+
nested_squares: StructureGenerators::NestedSquaresGenerator,
|
36
|
+
octagons: StructureGenerators::OctagonsGenerator,
|
37
|
+
overlapping_circles: StructureGenerators::OverlappingCirclesGenerator,
|
38
|
+
overlapping_rings: StructureGenerators::OverlappingRingsGenerator,
|
39
|
+
plaid: StructureGenerators::PlaidGenerator,
|
40
|
+
plus_signs: StructureGenerators::PlusSignsGenerator,
|
41
|
+
sine_waves: StructureGenerators::SineWavesGenerator,
|
42
|
+
squares: StructureGenerators::SquaresGenerator,
|
43
|
+
tessellation: StructureGenerators::TessellationGenerator,
|
44
|
+
triangles: StructureGenerators::TrianglesGenerator,
|
45
|
+
xes: StructureGenerators::XesGenerator
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def [](pattern)
|
50
|
+
$stderr.puts 'String pattern references are deprecated as of 1.3.0' if pattern.is_a?(String)
|
51
|
+
|
52
|
+
store[pattern.to_s.to_sym]
|
53
|
+
end
|
54
|
+
|
55
|
+
def all
|
56
|
+
store.values
|
57
|
+
end
|
58
|
+
|
59
|
+
def known?(pattern)
|
60
|
+
store.key?(pattern.to_s.to_sym)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GeoPattern
|
2
|
+
class PatternValidator
|
3
|
+
private
|
4
|
+
|
5
|
+
attr_reader :pattern_store
|
6
|
+
|
7
|
+
public
|
8
|
+
|
9
|
+
def initialize(pattern_store = PatternStore.new)
|
10
|
+
@pattern_store = pattern_store
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate(requested_patterns)
|
14
|
+
message = "Error: At least one of the requested patterns \"#{requested_patterns.join(', ')}\" is invalid"
|
15
|
+
|
16
|
+
fail InvalidPatternError, message unless valid?(requested_patterns)
|
17
|
+
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def valid?(requested_patterns)
|
24
|
+
requested_patterns.all? { |p| pattern_store.known? p }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module GeoPattern
|
6
|
+
# Rake Task
|
7
|
+
#
|
8
|
+
# This task can be used to generate pattern files
|
9
|
+
class RakeTask < ::Rake::TaskLib
|
10
|
+
include ::Rake::DSL if defined?(::Rake::DSL)
|
11
|
+
|
12
|
+
# @!attribute [r] name
|
13
|
+
# Name of task.
|
14
|
+
attr_reader :name
|
15
|
+
|
16
|
+
# @!attribute [r] description
|
17
|
+
# A description for the task
|
18
|
+
attr_reader :description
|
19
|
+
|
20
|
+
# @!attribute [r] verbose (true)
|
21
|
+
# Use verbose output. If this is set to true, the task will print the
|
22
|
+
# executed spec command to stdout.
|
23
|
+
attr_reader :verbose
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :task_arguments, :task_block, :logger, :working_directory
|
28
|
+
|
29
|
+
# Create task instance
|
30
|
+
#
|
31
|
+
# @param [String] description
|
32
|
+
# A description for the task
|
33
|
+
#
|
34
|
+
# @param [String] name
|
35
|
+
# The name for the task (including namespace), e.g. namespace1:task1
|
36
|
+
#
|
37
|
+
# @param [Array] arguments
|
38
|
+
# Arguments for the task. Look
|
39
|
+
# [here](http://viget.com/extend/protip-passing-parameters-to-your-rake-tasks)
|
40
|
+
# for a better description on how to use arguments in rake tasks
|
41
|
+
#
|
42
|
+
# @yield
|
43
|
+
# A block which is called before the "run_task"-method is called. The
|
44
|
+
# parameters it taskes depends on the number of parameters the block
|
45
|
+
# can take. If the block is defined which two parameters, it takes two
|
46
|
+
# parameters from the paramter 'arguments'.
|
47
|
+
def initialize(opts = {}, &task_block)
|
48
|
+
@options = {
|
49
|
+
description: nil,
|
50
|
+
name: GeoPattern::Helpers.underscore(self.class.to_s.split(/::/).slice(-2..-1).join(':').gsub(/Task$/, '')),
|
51
|
+
arguments: [],
|
52
|
+
logger: ::Logger.new($stderr),
|
53
|
+
working_directory: Dir.getwd
|
54
|
+
}.merge opts
|
55
|
+
|
56
|
+
before_initialize
|
57
|
+
|
58
|
+
fail ArgumentError, :description if @options[:description].nil?
|
59
|
+
|
60
|
+
@description = @options[:description]
|
61
|
+
@task_arguments = Array(@options[:arguments])
|
62
|
+
@task_block = task_block
|
63
|
+
@logger = @options[:logger]
|
64
|
+
@working_directory = @options[:working_directory]
|
65
|
+
@name = @options[:name]
|
66
|
+
|
67
|
+
after_initialize
|
68
|
+
|
69
|
+
define_task
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Run code after initialize
|
75
|
+
def after_initialize; end
|
76
|
+
|
77
|
+
# Run code before initialize
|
78
|
+
def before_initialize; end
|
79
|
+
|
80
|
+
# Define task
|
81
|
+
def define_task
|
82
|
+
desc description unless ::Rake.application.last_comment
|
83
|
+
|
84
|
+
task name, *task_arguments do |_, task_args|
|
85
|
+
RakeFileUtils.__send__(:verbose, verbose) do
|
86
|
+
instance_exec(*[self, task_args].slice(0, task_block.arity), &task_block) if task_block.respond_to? :call
|
87
|
+
run_task verbose
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Run code if task is executed
|
93
|
+
def run_task(_verbose); end
|
94
|
+
|
95
|
+
public
|
96
|
+
|
97
|
+
# Binding to instance
|
98
|
+
def instance_binding
|
99
|
+
binding
|
100
|
+
end
|
101
|
+
|
102
|
+
# Include module in instance
|
103
|
+
def include(modules)
|
104
|
+
modules = Array(modules)
|
105
|
+
|
106
|
+
modules.each { |m| self.class.include m }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|