noft 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +8 -0
- data/.gitignore +9 -0
- data/.node-version +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +5 -0
- data/LICENSE +201 -0
- data/README.md +65 -0
- data/Rakefile +18 -0
- data/bin/noft +8 -0
- data/lib/noft.rb +30 -0
- data/lib/noft/base/model.rb +50 -0
- data/lib/noft/base/templates/assets.rb +30 -0
- data/lib/noft/generator.rb +87 -0
- data/lib/noft/model.rb +132 -0
- data/lib/noft_plus.rb +20 -0
- data/lib/noft_plus/util.rb +29 -0
- data/noft.gemspec +35 -0
- data/test/fixtures/sample1/dist/fire-extinguisher.svg +1 -0
- data/test/fixtures/sample1/dist/fire-symbol.svg +1 -0
- data/test/fixtures/sample1/dist/fire.svg +1 -0
- data/test/fixtures/sample1/dist/sample1.noft.json +18 -0
- data/test/fixtures/sample1/webfont.svg +55 -0
- data/test/helper.rb +188 -0
- data/test/noft/base/templates/test_assets_template.rb +10 -0
- data/test/noft/test_generator.rb +47 -0
- data/test/noft/test_model.rb +135 -0
- metadata +217 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module Noft
|
16
|
+
module Base
|
17
|
+
class AssetsTemplate < Reality::Generators::SingleDirectoryOutputTemplate
|
18
|
+
def initialize(template_set, facets, target, template_key, output_directory_pattern, helpers, options = {})
|
19
|
+
super(template_set, facets, target, template_key, output_directory_pattern, helpers, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def generate_to_directory!(output_directory, element)
|
25
|
+
FileUtils.rm_rf output_directory
|
26
|
+
Noft::Generator.generate_assets(element.name, output_directory)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module Noft
|
16
|
+
class FontBlast < Schmooze::Base
|
17
|
+
dependencies fontBlast: 'font-blast'
|
18
|
+
|
19
|
+
method :blast, 'function(fontFile, destinationFolder, userConfig) {fontBlast(fontFile, destinationFolder, userConfig);}'
|
20
|
+
end
|
21
|
+
|
22
|
+
module Generator
|
23
|
+
EXTENSION = '.noft.json'
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def generate_assets(icon_set_name, output_directory)
|
27
|
+
icon_set = Noft.icon_set_by_name(icon_set_name)
|
28
|
+
FileUtils.rm_rf output_directory
|
29
|
+
|
30
|
+
metadata_file = "#{output_directory}/#{icon_set_name}#{EXTENSION}"
|
31
|
+
|
32
|
+
FileUtils.mkdir_p File.dirname(metadata_file)
|
33
|
+
|
34
|
+
icon_set.write_to(metadata_file)
|
35
|
+
|
36
|
+
# Generate filename mapping
|
37
|
+
filenames = {}
|
38
|
+
icon_set.icons.each { |icon| filenames[icon.unicode] = icon.name }
|
39
|
+
|
40
|
+
# Actually run the font blast to extract out the svg files
|
41
|
+
Noft::FontBlast.new('.').blast(icon_set.font_file, output_directory, { :filenames => filenames })
|
42
|
+
|
43
|
+
# Node writes the file asynchronously. This needs to be in place to ensure
|
44
|
+
# all the files are written as it is the last file to be generated
|
45
|
+
wait_until { File.exist?("#{output_directory}/verify.html") }
|
46
|
+
|
47
|
+
FileUtils.rm "#{output_directory}/verify.html"
|
48
|
+
FileUtils.mv "#{output_directory}/source-font.ttf", "#{output_directory}/font.ttf"
|
49
|
+
FileUtils.mv Dir["#{output_directory}/svg/*.svg"], output_directory
|
50
|
+
FileUtils.rmdir "#{output_directory}/svg"
|
51
|
+
|
52
|
+
reset_state_if_unchanged(output_directory)
|
53
|
+
|
54
|
+
output_directory
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# if the assets are stored in git and the only file that is modified is font.ttf
|
60
|
+
# then we can assume that there is no actual change, just a result of the underlying svg2ttf
|
61
|
+
# tool not giving a stable output given stable input. Unclear where the fault lies. In this
|
62
|
+
# scenario just reset the file.
|
63
|
+
# Note: svg2ttf uses current date for some fields even if you pass in a date. Also font-blast
|
64
|
+
# does not pass in a date.
|
65
|
+
def reset_state_if_unchanged(output_directory)
|
66
|
+
output = `git status -s #{output_directory}`
|
67
|
+
if output.split("\n").size == 1 && !(output =~ /^ M (.*\/)?font.ttf$/).nil?
|
68
|
+
`git checkout #{output_directory}/font.ttf`
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def wait_until(count = 100000, &block)
|
73
|
+
i = count
|
74
|
+
while i > 0
|
75
|
+
if block.call
|
76
|
+
break
|
77
|
+
else
|
78
|
+
i -= 1
|
79
|
+
Thread.pass
|
80
|
+
sleep 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
Noft.error('Node failed to generate the required files within an expected time frame') unless block.call
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/noft/model.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module Noft
|
16
|
+
Reality::Mda.define_system(Noft) do |r|
|
17
|
+
r.model_element(:icon_set)
|
18
|
+
r.model_element(:icon, :icon_set)
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def read_model(filename, filter = nil)
|
23
|
+
data = JSON.parse(IO.read(filename))
|
24
|
+
name = data['name']
|
25
|
+
Noft.error("Noft icon model configuration file '#{filename}' is missing a name") unless name
|
26
|
+
icon_set = Noft.icon_set(name.to_sym)
|
27
|
+
icon_set.read_from(data, filter)
|
28
|
+
icon_set
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Model #nodoc
|
33
|
+
class IconSet
|
34
|
+
# A human readable name for icon set
|
35
|
+
attr_accessor :display_string
|
36
|
+
attr_accessor :description
|
37
|
+
# The version of the source library from which this was extracted
|
38
|
+
attr_accessor :version
|
39
|
+
# The url to the source library
|
40
|
+
attr_accessor :url
|
41
|
+
# The license of the library
|
42
|
+
attr_accessor :license
|
43
|
+
# The url of the license
|
44
|
+
attr_accessor :license_url
|
45
|
+
# The local filename of the font file
|
46
|
+
attr_accessor :font_file
|
47
|
+
|
48
|
+
def font_file?
|
49
|
+
!(@font_file ||= nil).nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def write_to(filename)
|
53
|
+
File.write(filename, JSON.pretty_generate(to_h) + "\n")
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_from(data, filter = nil)
|
57
|
+
self.display_string = data['displayString'] if data['displayString']
|
58
|
+
self.description = data['description'] if data['description']
|
59
|
+
self.version = data['version'] if data['version']
|
60
|
+
self.url = data['url'] if data['url']
|
61
|
+
self.license = data['license'] if data['license']
|
62
|
+
self.license_url = data['licenseUrl'] if data['licenseUrl']
|
63
|
+
|
64
|
+
data['icons'].each_pair do |icon_name, icon_data|
|
65
|
+
if filter.nil? || (filter.is_a?(Proc) && filter.call(icon_name)) || (filter.is_a?(Array) && filter.include?(icon_name))
|
66
|
+
self.icon(icon_name.to_sym).read_from(icon_data)
|
67
|
+
end
|
68
|
+
end if data['icons']
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_h
|
72
|
+
data = {}
|
73
|
+
data[:name] = self.name
|
74
|
+
data[:displayString] = self.display_string if self.display_string
|
75
|
+
data[:description] = self.description if self.description
|
76
|
+
data[:version] = self.version if self.version
|
77
|
+
data[:url] = self.url if self.url
|
78
|
+
data[:license] = self.license if self.license
|
79
|
+
data[:licenseUrl] = self.license_url if self.license_url
|
80
|
+
|
81
|
+
data[:icons] = {}
|
82
|
+
self.icons.each do |icon|
|
83
|
+
data[:icons][icon.name] = icon.to_h
|
84
|
+
end
|
85
|
+
|
86
|
+
data
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Icon
|
91
|
+
# A human readable name for icon
|
92
|
+
attr_accessor :display_string
|
93
|
+
attr_accessor :description
|
94
|
+
|
95
|
+
# The unicode that it was assigned inside the font.
|
96
|
+
attr_accessor :unicode
|
97
|
+
|
98
|
+
# Categories which this Icon exists. Useful when displaying an icon sheet.
|
99
|
+
def categories
|
100
|
+
@categories ||= []
|
101
|
+
end
|
102
|
+
|
103
|
+
# Alternative aliases under which this icon may be known.
|
104
|
+
def aliases
|
105
|
+
@aliases ||= []
|
106
|
+
end
|
107
|
+
|
108
|
+
def read_from(data)
|
109
|
+
self.display_string = data['displayString'] if data['displayString']
|
110
|
+
self.description = data['description'] if data['description']
|
111
|
+
self.unicode = data['unicode'] if data['unicode']
|
112
|
+
data['aliases'].each do |a|
|
113
|
+
self.aliases << a
|
114
|
+
end if data['aliases']
|
115
|
+
data['categories'].each do |c|
|
116
|
+
self.categories << c
|
117
|
+
end if data['categories']
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_h
|
121
|
+
data = {}
|
122
|
+
data[:displayString] = self.display_string if self.display_string
|
123
|
+
data[:description] = self.description if self.description
|
124
|
+
data[:aliases] = self.aliases unless self.aliases.empty?
|
125
|
+
data[:categories] = self.categories unless self.categories.empty?
|
126
|
+
data[:unicode] = self.unicode if self.unicode
|
127
|
+
|
128
|
+
data
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/lib/noft_plus.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
require 'uri'
|
16
|
+
require 'net/http'
|
17
|
+
|
18
|
+
require 'noft'
|
19
|
+
|
20
|
+
require 'noft_plus/util'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module NoftPlus
|
16
|
+
module Util
|
17
|
+
class << self
|
18
|
+
|
19
|
+
# Download file to target unless it is already present
|
20
|
+
# Typically used to download font libraries from a remote location
|
21
|
+
def download_file(url, target_filename)
|
22
|
+
unless File.exist?(target_filename)
|
23
|
+
FileUtils.mkdir_p File.dirname(target_filename)
|
24
|
+
File.write(target_filename, Net::HTTP.get(URI(url)))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/noft.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{noft}
|
5
|
+
s.version = '1.0.0'
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
|
8
|
+
s.authors = ['Peter Donald']
|
9
|
+
s.email = %q{peter@realityforge.org}
|
10
|
+
|
11
|
+
s.homepage = %q{https://github.com/realityforge/noft}
|
12
|
+
s.summary = %q{A tool to extract svg icons from icon fonts and generate helpers to render the icons.}
|
13
|
+
s.description = %q{A tool to extract svg icons from icon fonts and generate helpers to render the icons.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
|
+
s.default_executable = []
|
19
|
+
s.require_paths = %w(lib)
|
20
|
+
|
21
|
+
s.has_rdoc = false
|
22
|
+
s.rdoc_options = %w(--line-numbers --inline-source --title noft)
|
23
|
+
|
24
|
+
s.add_dependency 'reality-mda', '>= 1.8.0'
|
25
|
+
s.add_dependency 'reality-core', '>= 1.8.0'
|
26
|
+
s.add_dependency 'reality-facets', '>= 1.9.0'
|
27
|
+
s.add_dependency 'reality-generators', '>= 1.13.0'
|
28
|
+
s.add_dependency 'reality-naming', '>= 1.9.0'
|
29
|
+
s.add_dependency 'reality-model', '>= 1.3.0'
|
30
|
+
s.add_dependency 'reality-orderedhash', '>= 1.0.0'
|
31
|
+
s.add_dependency 'schmooze', '= 0.1.6'
|
32
|
+
|
33
|
+
s.add_development_dependency(%q<minitest>, ['= 5.9.1'])
|
34
|
+
s.add_development_dependency(%q<test-unit>, ['= 3.1.5'])
|
35
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M473.093 32.314c2.517 1.882 3.768 4.497 3.774 7.842v100.39c0 3.345-1.256 5.96-3.768 7.844-1.674 1.462-3.772 2.195-6.276 2.195-.835 0-1.565-.105-2.192-.318l-140.548-30.114c-2.3-.417-4.183-1.567-5.652-3.45-1.463-1.883-2.193-3.975-2.193-6.277h-80.31v32.003c23.213 4.81 42.402 16.42 57.568 34.82 15.162 18.408 22.742 39.636 22.742 63.686v250.98c0 5.438-1.99 10.15-5.957 14.117-3.977 3.972-8.687 5.967-14.116 5.967h-160.63c-5.434 0-10.143-1.996-14.118-5.967-3.97-3.968-5.96-8.68-5.96-14.117v-250.98c0-22.168 6.535-42.09 19.606-59.765 13.076-17.673 29.963-29.645 50.667-35.917v-34.826h-10.035c-12.343 0-24.368 2.46-36.08 7.374-11.715 4.913-21.281 10.459-28.708 16.622-7.423 6.178-14.329 13.123-20.707 20.862-6.375 7.74-10.611 13.336-12.702 16.786s-3.554 6.015-4.395 7.686c-3.552 7.316-9.518 10.981-17.881 10.981-3.347 0-6.38-.732-9.099-2.194-4.813-2.51-8.105-6.38-9.88-11.61-1.78-5.23-1.414-10.352 1.096-15.372 1.044-2.09 2.565-4.81 4.549-8.156 1.987-3.347 5.91-8.94 11.763-16.784A201.868 201.868 0 0 1 72.63 114.66c6.8-6.794 15.69-13.803 26.668-21.016 10.981-7.216 22.327-12.706 34.04-16.468-5.232-8.784-7.844-17.78-7.844-26.983 0-13.805 4.91-25.621 14.744-35.45C150.065 4.913 161.885 0 175.69 0s25.62 4.913 35.452 14.744c9.83 9.829 14.745 21.645 14.745 35.45 0 6.9-1.466 13.594-4.395 20.08h94.746c0-2.305.726-4.395 2.189-6.273 1.465-1.884 3.35-3.036 5.655-3.45l140.548-30.117c.619-.21 1.352-.316 2.187-.316 2.51 0 4.6.731 6.277 2.196zM189.81 64.315c3.97-3.973 5.96-8.68 5.96-14.114 0-5.439-1.99-10.148-5.96-14.121-3.976-3.972-8.68-5.962-14.117-5.962s-10.147 1.99-14.121 5.962c-3.974 3.973-5.96 8.682-5.96 14.12 0 5.436 1.986 10.142 5.96 14.115 3.971 3.975 8.68 5.962 14.12 5.962s10.143-1.987 14.118-5.962z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M156.566 351.57c-8.57-12.28-15.477-26.62-20.717-43.002-5.238-16.38-7.851-33.904-7.851-52.572 0-14.855 2.336-28.57 7-41.143 4.669-12.57 10.761-23.285 18.285-32.143 7.525-8.855 15.857-17.238 25-25.14 9.141-7.905 18.286-15.288 27.431-22.143 9.143-6.86 17.475-13.717 25-20.573 7.524-6.86 13.617-14.62 18.286-23.286 4.667-8.665 7-17.856 7-27.571C256 46.095 249.716 24.76 237.147 0l.857.288-.285-.288c17.141 7.81 32.378 15.715 45.714 23.715 13.335 7.998 26.52 17.521 39.569 28.57 13.055 11.043 23.863 22.712 32.431 34.996 8.569 12.283 15.474 26.62 20.713 42.999 5.234 16.383 7.857 33.905 7.857 52.573 0 14.855-2.336 28.57-7 41.143-4.672 12.571-10.763 23.285-18.288 32.143-7.524 8.858-15.859 17.242-25 25.146-9.15 7.9-18.291 15.281-27.431 22.142-9.14 6.858-17.473 13.714-25 20.57-7.525 6.85-13.617 14.618-18.282 23.289-4.67 8.661-7.005 17.852-7.005 27.57 0 18.286 6.379 39.616 19.142 64l-1.144-.288.287.287c-17.142-7.814-32.38-15.716-45.716-23.72-13.338-8-26.523-17.523-39.572-28.567-13.046-11.046-23.857-22.718-32.428-34.998zM454.43 478.143c1.813 1.81 2.716 3.952 2.716 6.428v18.286c0 2.48-.908 4.62-2.716 6.431-1.812 1.813-3.952 2.713-6.425 2.713H63.997c-2.475 0-4.617-.9-6.428-2.713-1.81-1.811-2.713-3.951-2.713-6.431V484.57c0-2.476.904-4.619 2.713-6.428 1.81-1.804 3.953-2.705 6.428-2.705h384.008c2.473 0 4.613.9 6.425 2.705z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M158.874 512C50.247 450.78 21.649 392.832 38 313.689c12.07-58.44 56.647-105.986 60.437-164.314 16.884 30.726 18.888 52.882 20.775 84.99C172.912 168.572 228.602 80.521 216.56 0c0 0 101.81 32 142.986 188.14 24.325-21.639 22.04-66.226 10-92.563 36.122 26.338 243.61 260.159-32.578 416.424 51.928-101.104 13.396-237.527-76.761-300.532 6.023 27.092-1.504 97.833-41.39 142.233 9.031-45.906-13.546-75.255-13.546-75.255S197.87 320 169.15 361.979c-26.226 38.332-44.398 79.018-10.275 150.021z"/></svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"name": "sample1",
|
3
|
+
"displayString": "Sample 1",
|
4
|
+
"description": "Sample fonts downloaded from FlatIcon",
|
5
|
+
"version": "1",
|
6
|
+
"url": "http://www.flaticon.com/",
|
7
|
+
"icons": {
|
8
|
+
"fire-extinguisher": {
|
9
|
+
"unicode": "f100"
|
10
|
+
},
|
11
|
+
"fire-symbol": {
|
12
|
+
"unicode": "f101"
|
13
|
+
},
|
14
|
+
"fire": {
|
15
|
+
"unicode": "f102"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
3
|
+
<!--
|
4
|
+
2017-5-7: Created with FontForge (http://fontforge.org)
|
5
|
+
-->
|
6
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
7
|
+
<metadata>
|
8
|
+
Created by FontForge 20160405 at Sun May 7 06:58:20 2017
|
9
|
+
By Apache
|
10
|
+
Copyright (c) 2017, Apache
|
11
|
+
</metadata>
|
12
|
+
<defs>
|
13
|
+
<font id="Flaticon" horiz-adv-x="512" >
|
14
|
+
<font-face
|
15
|
+
font-family="Flaticon"
|
16
|
+
font-weight="400"
|
17
|
+
font-stretch="normal"
|
18
|
+
units-per-em="512"
|
19
|
+
panose-1="2 0 5 3 0 0 0 0 0 0"
|
20
|
+
ascent="448"
|
21
|
+
descent="-64"
|
22
|
+
bbox="33.7305 -64.001 478.27 448"
|
23
|
+
underline-thickness="25.6"
|
24
|
+
underline-position="-51.2"
|
25
|
+
unicode-range="U+0020-F102"
|
26
|
+
/>
|
27
|
+
<missing-glyph />
|
28
|
+
<glyph glyph-name="space" unicode=" " horiz-adv-x="200"
|
29
|
+
/>
|
30
|
+
<glyph glyph-name="uniF102" unicode=""
|
31
|
+
d="M158.874 -64c-108.627 61.2197 -137.225 119.168 -120.874 198.311c12.0703 58.4404 56.6465 105.986 60.4365 164.314c16.8848 -30.7256 18.8887 -52.8818 20.7754 -84.9902c53.7002 65.793 109.39 153.844 97.3477 234.365c0 0 101.811 -32 142.986 -188.139
|
32
|
+
c24.3252 21.6377 22.041 66.2256 10 92.5625c36.1221 -26.3379 243.61 -260.159 -32.5771 -416.424c51.9277 101.104 13.3955 237.527 -76.7617 300.532c6.02344 -27.0928 -1.50391 -97.833 -41.3906 -142.233c9.03223 45.9053 -13.5449 75.2549 -13.5449 75.2549
|
33
|
+
s-7.40234 -41.5537 -36.1221 -83.5322c-26.2266 -38.332 -44.3984 -79.0176 -10.2754 -150.021z" />
|
34
|
+
<glyph glyph-name="uniF100" unicode=""
|
35
|
+
d="M473.093 415.686c2.5166 -1.88184 3.76758 -4.49707 3.77441 -7.8418v-100.39c0 -3.34473 -1.25684 -5.95996 -3.76855 -7.84375c-1.67383 -1.46289 -3.77148 -2.19531 -6.27539 -2.19531c-0.835938 0 -1.56543 0.104492 -2.19238 0.317383l-140.548 30.1143
|
36
|
+
c-2.30078 0.416992 -4.18262 1.56738 -5.65234 3.4502c-1.46289 1.88281 -2.19238 3.97461 -2.19238 6.27734h-80.3096v-32.0029c23.2119 -4.80957 42.4014 -16.4199 57.5674 -34.8213c15.1621 -18.4072 22.7422 -39.6348 22.7422 -63.6855v-250.98
|
37
|
+
c0 -5.4375 -1.99023 -10.1494 -5.95703 -14.1162c-3.97754 -3.97266 -8.6875 -5.96777 -14.1162 -5.96777h-160.631c-5.43359 0 -10.1426 1.99609 -14.1172 5.96777c-3.96973 3.96777 -5.95996 8.67969 -5.95996 14.1162v250.98c0 22.168 6.53516 42.0898 19.6064 59.7656
|
38
|
+
c13.0752 17.6729 29.9629 29.6445 50.667 35.917v34.8262h-10.0352c-12.3428 0 -24.3682 -2.46094 -36.0811 -7.37402c-11.7139 -4.91309 -21.2803 -10.459 -28.707 -16.6221c-7.42285 -6.17871 -14.3291 -13.123 -20.707 -20.8623
|
39
|
+
c-6.375 -7.74023 -10.6113 -13.3359 -12.7021 -16.7861s-3.55371 -6.01465 -4.39453 -7.68555c-3.55273 -7.31641 -9.51855 -10.9814 -17.8818 -10.9814c-3.34668 0 -6.37988 0.732422 -9.09863 2.19434c-4.81348 2.50977 -8.10547 6.37891 -9.88086 11.6104
|
40
|
+
c-1.7793 5.22949 -1.41309 10.3516 1.09668 15.3711c1.04395 2.09082 2.56543 4.80957 4.54883 8.15625c1.9873 3.34668 5.91016 8.94043 11.7637 16.7842c5.85645 7.83984 12.1807 15.1631 18.9775 21.9609c6.80078 6.79395 15.6895 13.8027 26.668 21.0156
|
41
|
+
c10.9814 7.21582 22.3271 12.7061 34.04 16.4678c-5.23145 8.78418 -7.84375 17.7803 -7.84375 26.9834c0 13.8047 4.91016 25.6211 14.7441 35.4502c9.82812 9.83105 21.6475 14.7441 35.4521 14.7441s25.6191 -4.91309 35.4521 -14.7441
|
42
|
+
c9.8291 -9.8291 14.7441 -21.6455 14.7441 -35.4502c0 -6.90039 -1.46582 -13.5938 -4.39453 -20.0791h94.7461c0 2.30371 0.725586 4.39453 2.18848 6.27246c1.46582 1.88379 3.34961 3.03516 5.65527 3.4502l140.548 30.1162
|
43
|
+
c0.619141 0.210938 1.35254 0.316406 2.1875 0.316406c2.50879 0 4.59961 -0.731445 6.27637 -2.19629zM189.81 383.685c3.9707 3.97266 5.95996 8.67969 5.95996 14.1143c0 5.43848 -1.98926 10.1475 -5.95996 14.1211c-3.97559 3.97168 -8.67969 5.96191 -14.1172 5.96191
|
44
|
+
s-10.1465 -1.99023 -14.1211 -5.96191c-3.97363 -3.97363 -5.95996 -8.68262 -5.95996 -14.1211c0 -5.43555 1.98633 -10.1416 5.95996 -14.1143c3.97168 -3.97461 8.67969 -5.96191 14.1211 -5.96191s10.1426 1.9873 14.1172 5.96191z" />
|
45
|
+
<glyph glyph-name="uniF101" unicode=""
|
46
|
+
d="M156.566 96.4297c-8.57031 12.2812 -15.4766 26.6211 -20.7168 43.002c-5.23828 16.3809 -7.85156 33.9043 -7.85156 52.5723c0 14.8545 2.33594 28.5703 7 41.1426c4.66895 12.5713 10.7617 23.2852 18.2852 32.1436c7.52539 8.85449 15.8574 17.2373 25 25.1406
|
47
|
+
c9.1416 7.9043 18.2861 15.2871 27.4316 22.1426c9.14258 6.85938 17.4746 13.7168 25 20.5723c7.52344 6.85938 13.6162 14.6201 18.2852 23.2861c4.66699 8.66504 7 17.8564 7 27.5713c0 17.9023 -6.2832 39.2373 -18.8525 63.9971l0.856445 -0.288086l-0.28418 0.288086
|
48
|
+
c17.1406 -7.80957 32.3779 -15.7148 45.7139 -23.7148c13.335 -7.99805 26.5205 -17.5215 39.5684 -28.5703c13.0557 -11.043 23.8633 -22.7119 32.4316 -34.9961c8.56836 -12.2832 15.4736 -26.6191 20.7129 -42.999c5.2334 -16.3828 7.85645 -33.9053 7.85645 -52.5732
|
49
|
+
c0 -14.8545 -2.33594 -28.5703 -7 -41.1426c-4.67188 -12.5713 -10.7627 -23.2852 -18.2881 -32.1436c-7.52344 -8.85742 -15.8584 -17.2412 -24.999 -25.1455c-9.15137 -7.90039 -18.292 -15.2812 -27.4316 -22.1426c-9.14062 -6.85742 -17.4727 -13.7139 -25 -20.5693
|
50
|
+
c-7.52539 -6.85059 -13.6172 -14.6182 -18.2822 -23.2891c-4.66895 -8.66113 -7.00488 -17.8525 -7.00488 -27.5693c0 -18.2871 6.37891 -39.6172 19.1426 -64l-1.14453 0.287109l0.287109 -0.287109c-17.1416 7.81445 -32.3799 15.7158 -45.7158 23.7197
|
51
|
+
c-13.3379 8 -26.5234 17.5234 -39.5723 28.5674c-13.0459 11.0459 -23.8574 22.7178 -32.4277 34.998zM454.43 -30.1426c1.81348 -1.80957 2.71582 -3.95215 2.71582 -6.42871v-18.2852c0 -2.48047 -0.908203 -4.62012 -2.71582 -6.43164
|
52
|
+
c-1.8125 -1.8125 -3.95215 -2.71289 -6.4248 -2.71289h-384.008c-2.47559 0 -4.61719 0.900391 -6.42773 2.71289c-1.80957 1.81152 -2.71387 3.95117 -2.71387 6.43164v18.2852c0 2.47656 0.904297 4.61914 2.71387 6.42871
|
53
|
+
c1.80957 1.80371 3.95215 2.70508 6.42773 2.70508h384.008c2.47266 0 4.6123 -0.901367 6.4248 -2.70508z" />
|
54
|
+
</font>
|
55
|
+
</defs></svg>
|
data/test/helper.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'test/unit/assertions'
|
6
|
+
require 'noft'
|
7
|
+
|
8
|
+
module Noft
|
9
|
+
class << self
|
10
|
+
def reset
|
11
|
+
self.send(:icon_set_map).clear
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Noft::TestCase < Minitest::Test
|
17
|
+
include Test::Unit::Assertions
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@cwd = Dir.pwd
|
21
|
+
|
22
|
+
FileUtils.mkdir_p self.working_dir
|
23
|
+
Dir.chdir(self.working_dir)
|
24
|
+
File.write("#{self.working_dir}/package.json", package_json)
|
25
|
+
|
26
|
+
self.setup_node_modules
|
27
|
+
|
28
|
+
Noft.reset
|
29
|
+
end
|
30
|
+
|
31
|
+
def teardown
|
32
|
+
self.unlink_node_modules
|
33
|
+
Dir.chdir(@cwd)
|
34
|
+
if passed?
|
35
|
+
FileUtils.rm_rf self.working_dir if File.exist?(self.working_dir)
|
36
|
+
else
|
37
|
+
$stderr.puts "Test #{self.class.name}.#{name} Failed. Leaving working directory #{self.working_dir}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup_node_modules
|
42
|
+
node_modules_present = File.exist?(self.node_modules_dir)
|
43
|
+
FileUtils.mkdir_p self.node_modules_dir
|
44
|
+
FileUtils.ln_s(self.node_modules_dir, self.local_node_modules_dir)
|
45
|
+
system('npm install') unless node_modules_present
|
46
|
+
end
|
47
|
+
|
48
|
+
def unlink_node_modules
|
49
|
+
FileUtils.rm(self.local_node_modules_dir) if File.exist?(self.local_node_modules_dir)
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_file(filename, content)
|
53
|
+
expanded_filename = "#{working_dir}/#{filename}"
|
54
|
+
FileUtils.mkdir_p File.dirname(expanded_filename)
|
55
|
+
File.write(expanded_filename, content)
|
56
|
+
expanded_filename
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_filename(extension = '')
|
60
|
+
"#{working_dir}/#{::SecureRandom.hex}#{extension}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def local_dir(directory)
|
64
|
+
"#{working_dir}/#{directory}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def working_dir
|
68
|
+
@working_dir ||= "#{workspace_dir}/#{::SecureRandom.hex}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def workspace_dir
|
72
|
+
@workspace_dir ||= ENV['TEST_TMP_DIR'] || File.expand_path("#{File.dirname(__FILE__)}/../tmp/workspace")
|
73
|
+
end
|
74
|
+
|
75
|
+
def node_modules_dir
|
76
|
+
@node_modules_dir ||= "#{workspace_dir}/node_modules"
|
77
|
+
end
|
78
|
+
|
79
|
+
def local_node_modules_dir
|
80
|
+
"#{self.working_dir}/node_modules"
|
81
|
+
end
|
82
|
+
|
83
|
+
# The base test directory
|
84
|
+
def test_dir
|
85
|
+
@test_dir ||= File.expand_path("#{File.dirname(__FILE__)}")
|
86
|
+
end
|
87
|
+
|
88
|
+
# The fixtures directory
|
89
|
+
def fixture_dir
|
90
|
+
"#{test_dir}/fixtures"
|
91
|
+
end
|
92
|
+
|
93
|
+
def fixture(fixture_name)
|
94
|
+
"#{fixture_dir}/#{fixture_name}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def load_sample1_icon_set
|
98
|
+
# Load data from fixture json and make sure we link up all the non persisted attributes
|
99
|
+
|
100
|
+
icon_set = Noft.read_model(fixture('sample1/dist/sample1.noft.json'))
|
101
|
+
icon_set.font_file = fixture('sample1/webfont.svg')
|
102
|
+
|
103
|
+
icon_set.icon_by_name('fire-extinguisher').unicode = 'f100'
|
104
|
+
icon_set.icon_by_name('fire-symbol').unicode = 'f101'
|
105
|
+
icon_set.icon_by_name('fire').unicode = 'f102'
|
106
|
+
|
107
|
+
icon_set
|
108
|
+
end
|
109
|
+
|
110
|
+
def assert_sample1_dist_output(output_directory)
|
111
|
+
assert_dist_output(output_directory, 'sample1')
|
112
|
+
end
|
113
|
+
|
114
|
+
def assert_dist_output(output_directory, fixture_name)
|
115
|
+
assert_fixture_matches_output("#{fixture_name}/dist/fire.svg", "#{output_directory}/fire.svg")
|
116
|
+
assert_fixture_matches_output("#{fixture_name}/dist/fire-extinguisher.svg", "#{output_directory}/fire-extinguisher.svg")
|
117
|
+
assert_fixture_matches_output("#{fixture_name}/dist/fire-symbol.svg", "#{output_directory}/fire-symbol.svg")
|
118
|
+
assert_fixture_matches_output("#{fixture_name}/dist/sample1.noft.json", "#{output_directory}/sample1.noft.json")
|
119
|
+
|
120
|
+
assert_true File.exist?("#{output_directory}/font.ttf")
|
121
|
+
assert_false File.exist?("#{output_directory}/verify.html")
|
122
|
+
assert_false File.exist?("#{output_directory}/source-font.ttf")
|
123
|
+
assert_false File.exist?("#{output_directory}/svg")
|
124
|
+
end
|
125
|
+
|
126
|
+
def assert_fixture_matches_output(fixture_name, output_filename)
|
127
|
+
assert_equal true, File.exist?(output_filename), "Expected filename to be created #{output_filename}"
|
128
|
+
assert_equal IO.read(fixture(fixture_name)), IO.read(output_filename), "Content generated into #{output_filename}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def run_generators(template_set_keys, icon_set, options = {})
|
132
|
+
target_dir = options[:target_dir] || local_dir(::SecureRandom.hex)
|
133
|
+
filter = options[:filter]
|
134
|
+
Noft::TemplateSetManager.generator.generate(:icon_set, icon_set, target_dir, template_set_keys, filter)
|
135
|
+
target_dir
|
136
|
+
end
|
137
|
+
|
138
|
+
def in_dir(dir)
|
139
|
+
Dir.chdir(dir)
|
140
|
+
yield
|
141
|
+
end
|
142
|
+
|
143
|
+
def run_command(command)
|
144
|
+
output = `#{command}`
|
145
|
+
raise "Error executing command: #{command}\nOutput: #{output}" unless $?.success?
|
146
|
+
output
|
147
|
+
end
|
148
|
+
|
149
|
+
def update_dir_from_fixture(dir, fixture_name)
|
150
|
+
FileUtils.mkdir_p(dir)
|
151
|
+
FileUtils.cp_r("#{fixture(fixture_name)}/.", dir)
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_git_repo_from_fixture(fixture_name, options = {})
|
155
|
+
git_repo = options[:directory].nil? ? local_dir(fixture_name) : options[:directory]
|
156
|
+
create_git_repo(git_repo) do |dir|
|
157
|
+
update_dir_from_fixture(dir, fixture_name)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_git_repo(directory, &block)
|
162
|
+
FileUtils.mkdir_p directory
|
163
|
+
in_dir(directory) do
|
164
|
+
run_command('git init')
|
165
|
+
run_command("git config --local user.email \"user@example.org\"")
|
166
|
+
run_command("git config --local user.name \"A User\"")
|
167
|
+
block.call(directory)
|
168
|
+
run_command('git add *')
|
169
|
+
run_command("git commit -m \"initial commit\"")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def package_json
|
174
|
+
<<JSON
|
175
|
+
{
|
176
|
+
"name": "test-project",
|
177
|
+
"version": "1.0.0",
|
178
|
+
"description": "A project used to test",
|
179
|
+
"author": "",
|
180
|
+
"license": "Apache-2.0",
|
181
|
+
"repository": ".",
|
182
|
+
"devDependencies": {
|
183
|
+
"font-blast": "^0.6.1"
|
184
|
+
}
|
185
|
+
}
|
186
|
+
JSON
|
187
|
+
end
|
188
|
+
end
|