usps_flags 0.1.17

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.
@@ -0,0 +1,136 @@
1
+ # United States Power Squadrons® Flag Generator
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/usps_flags.svg)](https://badge.fury.io/rb/usps_flags)
4
+ [![Build Status](https://travis-ci.org/jfiander/usps-flags.svg)](https://travis-ci.org/jfiander/usps-flags)
5
+ [![Coverage Status](https://coveralls.io/repos/github/jfiander/usps-flags/badge.svg?branch=master)](https://coveralls.io/github/jfiander/usps-flags?branch=master)
6
+
7
+ This gem allows you to generate precise SVG and PNG flag images based on official specifications.
8
+
9
+ ## Installation
10
+
11
+ ### Rails
12
+
13
+ Add to your Gemfile:
14
+ ```ruby
15
+ gem 'usps_flags'
16
+ ```
17
+
18
+ Create the file `config/initializers/usps_flags.rb`:
19
+ ```ruby
20
+ USPSFlags::Config.flags_dir "#{Rails.root}/app/assets/images/flags"
21
+ ```
22
+
23
+ ### Other
24
+
25
+ Run `gem install usps_flags`.
26
+
27
+ Run `require 'usps_flags'` then `USPSFlags::Config.flags_dir "path/to/flags/dir"` to specify where to output all generated files and logs. (Otherwise, will default to `/output` in the gem directory.)
28
+
29
+ ## Available flags
30
+
31
+ - US Ensign
32
+ - USPS Ensign
33
+ - USPS Ensign Wheel logo
34
+ - Officer flags
35
+ - Officer insignia
36
+ - Official pennants
37
+
38
+ ## Generation
39
+
40
+ ### All files
41
+
42
+ To generate all static files, run:
43
+ ```ruby
44
+ USPSFlags::Generate.all svg: true, png: true, zips: true
45
+ ```
46
+
47
+ - Boolean arguments specify whether to process that set of files.
48
+
49
+ ### Zip archives
50
+
51
+ To re-generate zip files from current static files, run:
52
+ ```ruby
53
+ USPSFlags::Generate.zips svg: true, png: true
54
+ ```
55
+
56
+ - Boolean arguments specify whether to process that set of files.
57
+
58
+ ### Individual files
59
+
60
+ To generate an individual SVG file, run:
61
+ ```ruby
62
+ USPSFlags::Generate.get "flag", outfile: nil, scale: nil, field: true
63
+ ```
64
+
65
+ - `outfile` specifies where to save the file. If left as `nil`, this method will `puts` the generated SVG. Either way, the SVG code is returned.
66
+ - `scale` is a divisor scaling factor – the larger it is, the smaller the resulting SVG will be rendered. Accepted values are floats between 0 and 1, and integers above that.
67
+ - `field` specifies whether to render the field of a flag, or to only render the insignia. Setting this to `false` will invert some colors for visibility.
68
+
69
+ ### Trident spec sheet
70
+
71
+ To generate the trident spec sheet, run:
72
+ ```ruby
73
+ USPSFlags::Generate.spec outfile: nil, scale: nil, fly: 24, unit: "in"
74
+ ```
75
+
76
+ - `outfile` specifies where to save the file. If left as `nil`, this method will `puts` the generated SVG. Either way, the SVG code is returned.
77
+ - `scale` is a divisor scaling factor – the larger it is, the smaller the resulting SVG will be rendered. Accepted values are floats between 0 and 1, and integers above that.
78
+ - `fly` specifies the custom fly measurement to scale all trident labels to.
79
+ - `unit` specifies the custom fly measurement unit to append to all trident labels.
80
+
81
+ ### Convert SVG to PNG
82
+
83
+ To convert SVG data to a PNG image, run:
84
+ ```ruby
85
+ USPSFlags::Generate.png svg_data, outfile: nil, trim: false
86
+
87
+ # USPSFlags::Generate.png File.read("path/to/svg_image.svg"), outfile: "path/to/output.png", trim: false
88
+ # USPSFlags::Generate.png USPSFlags::Generate.get("LtC"), outfile: "path/to/output.png", trim: true
89
+ ```
90
+
91
+ - `outfile` is required, and specifies where to save the file.
92
+ - `trim` specifies whether to trim blank space from around the image. (This is ideal for generating insignia.)
93
+
94
+ ## Building
95
+
96
+ You can also build individual flags using the following DSL:
97
+
98
+ ```ruby
99
+ f = USPSFlags.new do
100
+ type "LtC"
101
+ scale 3
102
+ field false
103
+ trim true
104
+ svg_file "/path/to/svg/output.svg"
105
+ png_file "/path/to/png/output.png"
106
+ end
107
+
108
+ f.svg # Generate SVG file
109
+ f.png # Generate PNG file
110
+ ```
111
+
112
+ - Calling any DSL method without argument, or with `nil` as argument will return the current value.
113
+ - You can explicitly set `svg_file` to `""` to suppress printing the SVG content to console/log.
114
+ - Calling `.png` requires `png_file` to be set.
115
+
116
+ ## Security
117
+
118
+ This gem is cryptographically signed. To be sure the gem code hasn’t been tampered with:
119
+
120
+ Add my public key as a trusted certificate:
121
+
122
+ ```sh
123
+ gem cert --add <(curl -Ls https://raw.github.com/jfiander/usps-flags/master/certs/jfiander.pem)
124
+ ```
125
+
126
+ Then install the gem securely:
127
+
128
+ ```sh
129
+ gem install usps_flags -P HighSecurity
130
+ ```
131
+
132
+ ## License
133
+
134
+ Actual images generated (other than the US Ensign) are Copyright © United States Power Squadrons.
135
+
136
+ This gem is released under the [GPLv3](https://raw.github.com/jfiander/usps-flags/master/LICENSE).
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :spec
7
+ task test: :spec
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQ8wDQYDVQQDDAZqdWxp
3
+ YW4xFzAVBgoJkiaJk/IsZAEZFgdmaWFuZGVyMRMwEQYKCZImiZPyLGQBGRYDb25l
4
+ MB4XDTE3MTAxNzIwMzYwNVoXDTE4MTAxNzIwMzYwNVowPzEPMA0GA1UEAwwGanVs
5
+ aWFuMRcwFQYKCZImiZPyLGQBGRYHZmlhbmRlcjETMBEGCgmSJomT8ixkARkWA29u
6
+ ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgyweLKJcXOZUJ/Y/fb
7
+ IjGIQzFgi0UUbIxc6BRP3BYCAr7MpflEq3sYaVsECs0ZyM27zLpyDN0oW73Wby6k
8
+ jaik/yBcsDMvrl58+6mjHnB3yIuk0BbEfQaijgMBzW2p0hToocMToMXigwZOGe4e
9
+ kPTAO6yTIIYLhhjWALA+nURCBcCNI8d1YAIjiEuF1lCr4pnV4aAq8tPBVrz7a8Fg
10
+ WpeLe0V1Blhkg9BDzNUmSrDxDxitO8oA5+A0z9Wm1xn8cJfn50103813SEK8gaXV
11
+ eb/zLRa/CNnTzQ8xUrySd10b1auLnKduXgewBhINcWYjDOT/C1FCjxpK5F6buJ6S
12
+ 1ukCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFI/F
13
+ wfSc4YJ3gO9EnkvjGcT6fE3WMB0GA1UdEQQWMBSBEmp1bGlhbkBmaWFuZGVyLm9u
14
+ ZTAdBgNVHRIEFjAUgRJqdWxpYW5AZmlhbmRlci5vbmUwDQYJKoZIhvcNAQEFBQAD
15
+ ggEBAHddpCbrFKtf02u/4MPzRQQO+uTP9vlbNDxseQsMvpjIIzMjJzANGBqPeI+V
16
+ HCjLEnKtnUi9br+RqjtQWWc2jGBdZwrlhOFglKUcTVn60ZvBNrByUj8PeBHQR3U2
17
+ vEKSi1v2i/jlVVvrk+9z4DZ4QdrfARBcPCZhUSZcZBsDbnzjMeX6lhoknnqKn/oi
18
+ op1Z8vhtFmvxNk4UfHMG1bdUoxl6DDXKfodqWM//9mARZwSyVX9oV7snFP0nKUaD
19
+ 3YzYAc+kXfD7kkzA2NMvLT6Q1v03qQyIZ8BS8SNk5wLGAdLM+IravFDLEs448fjz
20
+ lEAU0RHLFVbE+CXW6makIlWGHR0=
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,37 @@
1
+ # Monkey patch to add some formatting methods to Rational.
2
+ #
3
+ # @author Julian Fiander
4
+ # @since 0.1.5
5
+ class Rational
6
+ # Converts Rational to String
7
+ #
8
+ # If Rational is an improper fraction, removes the integer part to convert to a mixed fraction.
9
+ #
10
+ # @example Mixed fraction
11
+ # Rational(4,3).to_simplified_s #=> "1 1/3"
12
+ # @return [String] If less than 1, fraction. If greater than 1, a mixed fraction.
13
+ def to_simplified_s
14
+ if self < 1
15
+ to_s
16
+ else
17
+ truncated = self.truncate
18
+ "#{truncated} #{self - truncated}"
19
+ end
20
+ end
21
+
22
+ # Converts Rational to Array
23
+ #
24
+ # If Rational is an improper fraction, removes the integer part to convert to a mixed fraction.
25
+ #
26
+ # @example Mixed fraction
27
+ # Rational(4,3).to_simplified_a #=> [1, Rational(1,3)]
28
+ # @return [Array] If less than 1, fraction. If greater than 1, a mixed fraction.
29
+ def to_simplified_a
30
+ if self < 1
31
+ to_s
32
+ else
33
+ truncated = self.truncate
34
+ [truncated, (self - truncated)]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,140 @@
1
+ # Base class for the namespace. Provides a constructor DSL.
2
+ #
3
+ # @author Julian Fiander
4
+ # @since 0.1.5
5
+ class USPSFlags
6
+ require 'fileutils'
7
+ require 'zip'
8
+ require 'mini_magick'
9
+ require 'rational'
10
+ require 'usps_flags/config'
11
+ require 'usps_flags/helpers'
12
+ require 'usps_flags/core'
13
+ require 'usps_flags/generate'
14
+
15
+ # Constructor for individual flags.
16
+ #
17
+ # @example Generate insignia at default scale for Lt/C
18
+ # f = USPSFlags.new do
19
+ # type "LtC"
20
+ # scale 3
21
+ # field false
22
+ # trim true
23
+ # svg_file "/path/to/svg/output.svg"
24
+ # png_file "/path/to/png/output.png"
25
+ # end
26
+ #
27
+ # f.svg #=> Generates SVG file at "/path/to/svg/output.svg"
28
+ # f.png #=> Generates PNG file at "/path/to/png/output.png"
29
+ def initialize(&block)
30
+ @type = nil
31
+ @svg_file = nil
32
+ @png_file = nil
33
+ @scale = nil
34
+ @field = nil
35
+ @trim = nil
36
+ instance_eval(&block) if block_given?
37
+ end
38
+
39
+ # Constructor accessor for the flag type.
40
+ #
41
+ # @param [String] type If set, updates the constructor's flag type.
42
+ # @return [String] Returns the current (or updated) flag type.
43
+ def type(string = nil)
44
+ if string.nil?
45
+ @type
46
+ else
47
+ @type = string
48
+ self
49
+ end
50
+ end
51
+
52
+ # Constructor accessor for the SVG file output path.
53
+ #
54
+ # @param [String] svg_file If set, updates the constructor's SVG file output path.
55
+ # @return [String] Returns the current (or updated) SVG file output path.
56
+ def svg_file(string = nil)
57
+ if string.nil?
58
+ @svg_file
59
+ else
60
+ @svg_file = string
61
+ self
62
+ end
63
+ end
64
+
65
+ # Constructor accessor for the PNG file output path.
66
+ #
67
+ # @param [String] png_file If set, updates the constructor's PNG file output path.
68
+ # @return [String] Returns the current (or updated) PNG file output path.
69
+ def png_file(string = nil)
70
+ if string.nil?
71
+ @png_file
72
+ else
73
+ @png_file = string
74
+ self
75
+ end
76
+ end
77
+
78
+ # Constructor accessor for the image scale divisor factor.
79
+ #
80
+ # Available options are Float between 0 and 1, or Integer above 1.
81
+ #
82
+ # @param [Integer, Float] scale If set, updates the constructor's scale divisor factor.
83
+ # @return [Integer, Float] Returns the current (or updated) scaling factor.
84
+ def scale(num = nil)
85
+ if num.nil?
86
+ @scale
87
+ else
88
+ @scale = num
89
+ self
90
+ end
91
+ end
92
+
93
+ # Constructor accessor for whether to generate the flag field (including any border).
94
+ #
95
+ # @param [Boolean] field If set, updates the constructor's field setting.
96
+ # @return [Boolean] Returns the current (or updated) setting.
97
+ def field(bool = nil)
98
+ if bool.nil?
99
+ @field
100
+ else
101
+ @field = bool
102
+ self
103
+ end
104
+ end
105
+
106
+ # Constructor accessor for whether to trim the generated PNG file of excess transparency.
107
+ #
108
+ # @param [Boolean] trim If set, updates the constructor's trim setting.
109
+ # @return [String] Returns the current (or updated) setting.
110
+ def trim(bool = nil)
111
+ if bool.nil?
112
+ @trim
113
+ else
114
+ @trim = bool
115
+ self
116
+ end
117
+ end
118
+
119
+ # Generates the constructed file as SVG.
120
+ #
121
+ # @return [String] Returns the SVG file output path, or the svg data if no path was specified.
122
+ def svg
123
+ svg = USPSFlags::Generate.get(self.type, outfile: self.svg_file, scale: self.scale, field: self.field)
124
+ (self.svg_file.nil? || self.svg_file == "") ? svg : self.svg_file
125
+ end
126
+
127
+ # Generates the constructed file as PNG.
128
+ #
129
+ # Requires the constructor to have a value for png_file.
130
+ #
131
+ # @return [String] Returns the SVG file output path.
132
+ def png
133
+ raise "Error: png_file must be set." if self.png_file.nil?
134
+ svg_file_storage = self.svg_file
135
+ self.svg_file ""
136
+ USPSFlags::Generate.png(self.svg, outfile: self.png_file, trim: self.trim)
137
+ self.svg_file svg_file_storage
138
+ self.png_file
139
+ end
140
+ end
@@ -0,0 +1,115 @@
1
+ # Container class for configuration values.
2
+ class USPSFlags::Config
3
+ BLUE ||= "#041E42" # Old Glory Blue
4
+ RED ||= "#BF0D3E" # Old Glory Red
5
+
6
+ # Base measurements for most flags, before scaling
7
+ BASE_FLY ||= 3072
8
+ BASE_HOIST ||= BASE_FLY*2/3
9
+ FRACTION_SCALE ||= 85
10
+
11
+ @@flags_dir ||= "#{File.dirname(__dir__)}/output"
12
+ @@use_larger_tridents ||= true
13
+
14
+ # Accessor for the directory for storing generated flags.
15
+ #
16
+ # @param [String] init If set, updates the path to the directory for storing generated flags.
17
+ # @param [Boolean] reset Delete all files in the specified directory if found.
18
+ # @example Update flag storage directory
19
+ # # Rails.root => "/path/to"
20
+ # USPSFlags::Config.flags_dir "#{Rails.root}/app/assets/images/flags" #=> "/path/to/app/assets/images/flags"
21
+ # @example Update flag storage directory that already has some files in it
22
+ # # Rails.root => "/path/to"
23
+ # USPSFlags::Config.flags_dir "#{Rails.root}/app/assets/images/flags", reset: true #=> "/path/to/app/assets/images/flags"
24
+ # @return [String] Returns the current (or updated) path to the flags directory.
25
+ def self.flags_dir(init = nil, reset: false)
26
+ unless init.nil?
27
+ @@flags_dir = init
28
+ ::FileUtils.rm_rf(USPSFlags::Config.flags_dir) if reset
29
+ [
30
+ "#{USPSFlags::Config.flags_dir}/SVG/insignia",
31
+ "#{USPSFlags::Config.flags_dir}/PNG/insignia",
32
+ "#{USPSFlags::Config.flags_dir}/ZIP"
33
+ ].each do |dir|
34
+ ::FileUtils.mkdir_p(dir)
35
+ end
36
+ ::FileUtils.mkdir_p(USPSFlags::Config.log_path) unless defined?(Rails)
37
+ end
38
+ @@flags_dir
39
+ end
40
+
41
+ # Alias for the directory to store generated log files.
42
+ #
43
+ # @example Rails
44
+ # # Rails.root => "/path/to"
45
+ # USPSFlags::Config.logs_dir #=> "/path/to/log"
46
+ #
47
+ # @example Non-Rails
48
+ # USPSFlags::Config.logs_dir #=> "/app/root/log"
49
+ def self.log_path
50
+ if defined?(Rails)
51
+ "#{Rails.root}/log"
52
+ else
53
+ log_dir = "#{self.flags_dir}/log"
54
+ ::FileUtils.mkdir_p(log_dir)
55
+ log_dir
56
+ end
57
+ end
58
+
59
+ # Accessor for the boolean of whether to use the larger or smaller trident width.
60
+ #
61
+ # @param [Boolean] bool If set to a Boolean, specify whether to use the larger trident width.
62
+ # @return [Boolean] Returns the current (or updated) setting.
63
+ def self.use_larger_tridents(bool = nil)
64
+ # Smaller: 1/2 in width on 24in x 16in field
65
+ # Larger: 5/8 in width on 24in x 16in field
66
+ @@use_larger_tridents = bool unless bool.nil? || !([true, false].include?(bool))
67
+ @@use_larger_tridents
68
+ end
69
+
70
+ # Base configuration values for trident insignia.
71
+ #
72
+ # All other values are derived from these, or directly from the constant sizes.
73
+ #
74
+ # @return [Hash] Returns the configuration values for tridents.
75
+ def self.trident
76
+ point_height = USPSFlags::Config::BASE_FLY/48*17/8
77
+ bar_width = USPSFlags::Config::BASE_FLY/48
78
+ bar_width = bar_width*5/4 if self.use_larger_tridents
79
+ {
80
+ height: {
81
+ s: USPSFlags::Config::BASE_HOIST/2,
82
+ d: USPSFlags::Config::BASE_HOIST*5/8,
83
+ stf: USPSFlags::Config::BASE_HOIST*3/4,
84
+ n: USPSFlags::Config::BASE_HOIST*3/4
85
+ },
86
+
87
+ center_point: BASE_FLY/2,
88
+
89
+ width: USPSFlags::Config::BASE_FLY*5/32,
90
+
91
+ bar_width: bar_width,
92
+
93
+ point_height: point_height,
94
+
95
+ main_point_barb: USPSFlags::Config::BASE_HOIST/240,
96
+
97
+ crossbar_from_top: USPSFlags::Config::BASE_HOIST/4,
98
+
99
+ side_spike_height: USPSFlags::Config::BASE_HOIST/4-point_height-bar_width,
100
+
101
+ hash_width: USPSFlags::Config::BASE_FLY*3/32,
102
+
103
+ delta_height: USPSFlags::Config::BASE_FLY*2/15,
104
+ delta_gap_height: self.use_larger_tridents ? USPSFlags::Config::BASE_FLY*14/256 : USPSFlags::Config::BASE_FLY*17/256,
105
+ delta_gap_width: self.use_larger_tridents ? bar_width*5/4 : bar_width*7/4,
106
+ delta_width: USPSFlags::Config::BASE_FLY*43/768,
107
+ delta_from_bottom: USPSFlags::Config::BASE_HOIST*11/64,
108
+ delta_gap_scale: 0.40,
109
+ delta_gap_x: USPSFlags::Config::BASE_HOIST*144/128,
110
+ delta_gap_y: USPSFlags::Config::BASE_HOIST*221/256,
111
+
112
+ circle_height_adj: USPSFlags::Config::BASE_FLY/800
113
+ }
114
+ end
115
+ end