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.
@@ -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
@@ -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
@@ -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
@@ -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="&#xf102;"
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="&#xf100;"
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="&#xf101;"
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>
@@ -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