noft 1.0.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 +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
|