hieroglyph 0.1.1 → 0.1.2
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.
- data/-rf +0 -0
- data/Gemfile +11 -2
- data/README.md +48 -19
- data/Rakefile +14 -2
- data/hieroglyph.gemspec +9 -14
- data/lib/hieroglyph.rb +21 -13
- data/lib/hieroglyph/assets/fontsquirrel-subsetting.jpg +0 -0
- data/lib/hieroglyph/assets/footer +1 -2
- data/lib/hieroglyph/assets/glyphs/-private_unicode.svg +19 -0
- data/lib/hieroglyph/assets/glyphs/C-checkcircle.svg +4 -4
- data/lib/hieroglyph/assets/glyphs/a-star.svg +13 -14
- data/lib/hieroglyph/assets/glyphs/c-check.svg +3 -2
- data/lib/hieroglyph/assets/glyphs/d-downcaret.svg +2 -2
- data/lib/hieroglyph/assets/glyphs/e-invalid_shapes-BAD.svg +14 -0
- data/lib/hieroglyph/assets/glyphs/f-too_many_shapes-BAD.svg +651 -0
- data/lib/hieroglyph/assets/header +0 -2
- data/lib/hieroglyph/character_sheet.rb +28 -36
- data/lib/hieroglyph/command_line.rb +11 -3
- data/lib/hieroglyph/font.rb +23 -25
- data/lib/hieroglyph/glyph.rb +87 -29
- data/lib/hieroglyph/noop_sheet.rb +13 -0
- data/lib/hieroglyph/version.rb +1 -1
- data/rm +0 -0
- data/spec/lib/hieroglyph/character_sheet_spec.rb +20 -35
- data/spec/lib/hieroglyph/font_spec.rb +70 -2
- data/spec/lib/hieroglyph/glyph_spec.rb +116 -2
- data/spec/lib/hieroglyph/noop_sheet_spec.rb +26 -0
- data/spec/spec_helper.rb +3 -15
- data/spec/support/flipped_path +1 -0
- data/spec/support/normal_path +1 -0
- data/spec/support/test-polygon.svg +8 -0
- data/spec/support/test.svg +19 -0
- metadata +23 -50
@@ -1,48 +1,40 @@
|
|
1
1
|
module Hieroglyph
|
2
2
|
|
3
|
-
|
4
|
-
class CharacterSheet
|
3
|
+
class CharacterSheet
|
5
4
|
|
6
|
-
|
7
|
-
@options = options
|
8
|
-
@output_path = File.join(@options[:output_folder], @options[:name]) + "_characters.png"
|
9
|
-
if File.exist? @output_path
|
10
|
-
Hieroglyph.log " #{@output_path} exists, deleting"
|
11
|
-
File.delete @output_path
|
12
|
-
end
|
13
|
-
@characters = Magick::ImageList.new
|
14
|
-
end
|
5
|
+
attr_accessor :files, :output_path
|
15
6
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
@@montage_args = {
|
8
|
+
'background' => '#ffffff',
|
9
|
+
'fill' => '#000000',
|
10
|
+
'geometry' => '150x150+25+25',
|
11
|
+
'label' => '%t',
|
12
|
+
'mattecolor' => '#ffffff'
|
13
|
+
}
|
21
14
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
self.fill = "#000000"
|
29
|
-
self.geometry = "150x150+10+5"
|
30
|
-
self.matte_color = "#ffffff"
|
31
|
-
self.title = name
|
32
|
-
end
|
33
|
-
img.write(@output_path)
|
34
|
-
end
|
15
|
+
def initialize(options)
|
16
|
+
@options = options
|
17
|
+
@output_path = File.join(@options[:output_folder], @options[:name]) + '_characters.png'
|
18
|
+
Hieroglyph.delete @output_path
|
19
|
+
@files = []
|
20
|
+
Hieroglyph.log 'ImageMagick detected - generating character sheet'
|
35
21
|
end
|
36
22
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
23
|
+
def add(file)
|
24
|
+
@files.push file
|
25
|
+
end
|
26
|
+
|
27
|
+
def save
|
28
|
+
cmd = 'montage'
|
29
|
+
@@montage_args['title'] = @options[:name]
|
30
|
+
@@montage_args.each do |arg, value|
|
31
|
+
cmd << " -#{arg} #{value}"
|
43
32
|
end
|
44
|
-
|
33
|
+
@files.each do |file|
|
34
|
+
cmd << " #{file}"
|
45
35
|
end
|
36
|
+
cmd << " #{@output_path}"
|
37
|
+
`#{cmd}`
|
46
38
|
end
|
47
39
|
end
|
48
40
|
|
@@ -18,9 +18,17 @@ Options:
|
|
18
18
|
@execute = true
|
19
19
|
parse_options
|
20
20
|
if @execute
|
21
|
-
Hieroglyph.make @options
|
22
|
-
Hieroglyph.
|
23
|
-
Hieroglyph.log "
|
21
|
+
font = Hieroglyph.make @options
|
22
|
+
Hieroglyph.header "#{@options[:name]} generated"
|
23
|
+
Hieroglyph.log "Saved to #{@options[:output_folder]}"
|
24
|
+
Hieroglyph.log "To create a full set of webfonts, upload to:"
|
25
|
+
Hieroglyph.log "http://www.fontsquirrel.com/fontface/generator"
|
26
|
+
Hieroglyph.log
|
27
|
+
Hieroglyph.log "If you're having trouble uploading SVGs, try converting to a TTF first using http://www.freefontconverter.com"
|
28
|
+
Hieroglyph.log
|
29
|
+
Hieroglyph.log "Single characters: #{font.characters.join(',')}"
|
30
|
+
Hieroglyph.log "Unicode characters: #{font.unicode_values.join(',')}"
|
31
|
+
Hieroglyph.log
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
data/lib/hieroglyph/font.rb
CHANGED
@@ -2,40 +2,38 @@ module Hieroglyph
|
|
2
2
|
|
3
3
|
class Font
|
4
4
|
|
5
|
+
attr_accessor :output_path, :options, :characters, :unicode_values, :contents, :character_sheet
|
6
|
+
|
5
7
|
def initialize(options)
|
8
|
+
@characters = []
|
9
|
+
@unicode_values = []
|
10
|
+
@contents = ""
|
6
11
|
@options = options
|
7
12
|
@output_path = File.join(@options[:output_folder], @options[:name] + ".svg")
|
8
|
-
@contents = ""
|
9
13
|
setup
|
10
14
|
add_glyphs
|
11
15
|
finish
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
header.gsub!("{{NAME}}", @options[:name])
|
18
|
-
add header
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_footer
|
22
|
-
footer_path = File.join(File.dirname(__FILE__), "assets/footer")
|
23
|
-
footer = File.open(footer_path).read
|
24
|
-
add footer
|
18
|
+
def include(file)
|
19
|
+
path = File.join(File.dirname(__FILE__), "assets/#{file}")
|
20
|
+
add File.open(path).read
|
25
21
|
end
|
26
22
|
|
27
|
-
def setup
|
28
|
-
Hieroglyph.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
23
|
+
def setup
|
24
|
+
Hieroglyph.header "Generating #{@options[:name]}"
|
25
|
+
Hieroglyph.delete @output_path
|
26
|
+
@character_sheet = Hieroglyph.imagemagick_installed? ? CharacterSheet.new(@options) : NoopSheet.new
|
27
|
+
include 'header'
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_name
|
31
|
+
@contents.gsub!("{{NAME}}", @options[:name])
|
35
32
|
end
|
36
33
|
|
37
34
|
def finish
|
38
|
-
|
35
|
+
include "footer"
|
36
|
+
set_name
|
39
37
|
File.open(@output_path, "w") do |file|
|
40
38
|
file.puts @contents
|
41
39
|
file.close
|
@@ -48,10 +46,10 @@ module Hieroglyph
|
|
48
46
|
end
|
49
47
|
|
50
48
|
def add_glyphs
|
51
|
-
Hieroglyph.log
|
52
|
-
Dir.glob(File.join(@options[:glyph_folder],
|
53
|
-
glyph = Glyph.new(file, @options[:glyph_folder])
|
54
|
-
@character_sheet.add
|
49
|
+
Hieroglyph.log
|
50
|
+
Dir.glob(File.join(@options[:glyph_folder], '*.svg')).each do |file|
|
51
|
+
glyph = Glyph.new(file, @options[:glyph_folder], self)
|
52
|
+
@character_sheet.add file
|
55
53
|
add glyph.to_node
|
56
54
|
end
|
57
55
|
end
|
data/lib/hieroglyph/glyph.rb
CHANGED
@@ -5,19 +5,94 @@ module Hieroglyph
|
|
5
5
|
|
6
6
|
class Glyph
|
7
7
|
|
8
|
-
attr_accessor :name
|
8
|
+
attr_accessor :name, :path, :contents
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
SHAPE_HANDLERS = {
|
11
|
+
'circle' => 'report_invalid',
|
12
|
+
'ellipse' => 'report_invalid',
|
13
|
+
'line' => 'report_invalid',
|
14
|
+
'polyline' => 'report_invalid',
|
15
|
+
'rect' => 'report_invalid',
|
16
|
+
'polygon' => 'convert_polygon',
|
17
|
+
'path' => 'convert_path'
|
18
|
+
}
|
19
|
+
|
20
|
+
NAME_REGEX = /^..*?(?=(-|\.))/
|
21
|
+
|
22
|
+
UNICODE_REGEX = /(?<=^&#(x|X)).*(?=;)/
|
23
|
+
|
24
|
+
@@too_many_shapes = false
|
25
|
+
|
26
|
+
def initialize(file, source, font)
|
27
|
+
@font = font
|
28
|
+
set_name(file, source)
|
13
29
|
@contents = Nokogiri::XML(File.new(file))
|
14
|
-
@
|
15
|
-
@path =
|
16
|
-
|
30
|
+
Hieroglyph.log "#{@name} -> reading...", 4
|
31
|
+
@path = parse_shapes
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_name(file, source)
|
35
|
+
@name = file.gsub(source, '').gsub('/', '').match(NAME_REGEX).to_s
|
36
|
+
unicode = @name.match(UNICODE_REGEX)
|
37
|
+
if unicode
|
38
|
+
@font.unicode_values.push(unicode.to_s.upcase)
|
39
|
+
else
|
40
|
+
@font.characters.push(@name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_shapes
|
45
|
+
path = Savage::Path.new
|
46
|
+
count = 0
|
47
|
+
SHAPE_HANDLERS.each do |type, method|
|
48
|
+
contents = @contents.root.at_css(type)
|
49
|
+
if contents
|
50
|
+
count += 1
|
51
|
+
if count > 1
|
52
|
+
report_too_many
|
53
|
+
else
|
54
|
+
path = self.method(method).call(type, contents)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
path
|
17
59
|
end
|
18
60
|
|
19
|
-
def
|
20
|
-
|
61
|
+
def convert_polygon(type, content)
|
62
|
+
Hieroglyph.log "polygon found - converting", 9
|
63
|
+
points = content["points"].split(" ")
|
64
|
+
Savage::Path.new do |path|
|
65
|
+
start_position = points.shift.split(",")
|
66
|
+
path.move_to(start_position[0], start_position[1])
|
67
|
+
points.each do |point|
|
68
|
+
position = point.split(",")
|
69
|
+
path.line_to(position[0], position[1])
|
70
|
+
end
|
71
|
+
path.close_path
|
72
|
+
flip(path)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def convert_path(type, content)
|
77
|
+
Hieroglyph.log 'path found', 9
|
78
|
+
path = Savage::Parser.parse content['d']
|
79
|
+
flip(path)
|
80
|
+
end
|
81
|
+
|
82
|
+
def report_invalid(type, content)
|
83
|
+
Hieroglyph.log "#{type} found - this shape is invalid!", 9
|
84
|
+
Hieroglyph.log "'make compound path' in your vector tool to fix", 9
|
85
|
+
end
|
86
|
+
|
87
|
+
def report_too_many
|
88
|
+
unless @too_many
|
89
|
+
Hieroglyph.log 'too many shapes! your icon might look weird as a result', 9
|
90
|
+
@too_many = true
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def flip(path)
|
95
|
+
path.subpaths.each do |subpath|
|
21
96
|
subpath.directions.each do |direction|
|
22
97
|
case direction
|
23
98
|
when Savage::Directions::MoveTo
|
@@ -55,34 +130,17 @@ module Hieroglyph
|
|
55
130
|
end
|
56
131
|
end
|
57
132
|
end
|
58
|
-
|
59
|
-
|
60
|
-
def convert_path
|
61
|
-
@path = @contents.root.at_css("path")["d"]
|
62
|
-
@path = Savage::Parser.parse @path
|
63
|
-
end
|
64
|
-
|
65
|
-
def convert_polygon
|
66
|
-
Hieroglyph.log " -> converting polygon to path"
|
67
|
-
points = @polygon["points"].split(" ")
|
68
|
-
Savage::Path.new do |path|
|
69
|
-
start_position = points.shift.split(",")
|
70
|
-
path.move_to(start_position[0], start_position[1])
|
71
|
-
points.each do |point|
|
72
|
-
position = point.split(",")
|
73
|
-
path.line_to(position[0], position[1])
|
74
|
-
end
|
75
|
-
path.close_path
|
76
|
-
end
|
133
|
+
path
|
77
134
|
end
|
78
135
|
|
79
136
|
def flip_y(value)
|
80
137
|
value = value.to_f
|
81
138
|
value = (value - 500) * -1 + 500
|
139
|
+
value = value - 25
|
82
140
|
end
|
83
141
|
|
84
142
|
def to_node
|
85
|
-
|
143
|
+
@path ? "<glyph unicode=\"#{@name}\" d=\"#{@path.to_command}\" />\n" : ''
|
86
144
|
end
|
87
145
|
|
88
146
|
end
|
data/lib/hieroglyph/version.rb
CHANGED
data/rm
ADDED
File without changes
|
@@ -1,49 +1,34 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hieroglyph::CharacterSheet do
|
4
|
-
context
|
5
|
-
before :each do
|
6
|
-
@characters = stub(:push)
|
7
|
-
Magick::ImageList.stubs(:new).returns(@characters)
|
4
|
+
context 'A CharacterSheet' do
|
8
5
|
|
6
|
+
before :each do
|
7
|
+
module Hieroglyph
|
8
|
+
def self.log(*)
|
9
|
+
end
|
10
|
+
def self.header(*)
|
11
|
+
end
|
12
|
+
end
|
9
13
|
@character_sheet = Hieroglyph::CharacterSheet.new({:output_folder => '/tmp', :name => 'sheet'})
|
14
|
+
@path = File.expand_path('../../../support/test.svg', __FILE__)
|
10
15
|
end
|
11
16
|
|
12
|
-
it
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@character_sheet.add('a file', 'some name')
|
17
|
+
it 'sets the correct output path' do
|
18
|
+
@character_sheet.output_path.should eql '/tmp/sheet_characters.png'
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
@
|
21
|
+
it 'adds a file with a given name' do
|
22
|
+
puts @path
|
23
|
+
@character_sheet.add(@path)
|
24
|
+
@character_sheet.files.should eql [@path]
|
21
25
|
end
|
22
26
|
|
23
27
|
it 'saves the files into one image' do
|
24
|
-
|
25
|
-
|
26
|
-
@characters.stubs(:montage).yields.returns(image)
|
27
|
-
|
28
|
-
@character_sheet.stubs(:background_color=)
|
29
|
-
@character_sheet.stubs(:border_width=)
|
30
|
-
@character_sheet.stubs(:border_color=)
|
31
|
-
@character_sheet.stubs(:fill=)
|
32
|
-
@character_sheet.stubs(:geometry=)
|
33
|
-
@character_sheet.stubs(:matte_color=)
|
34
|
-
@character_sheet.stubs(:title=)
|
35
|
-
|
28
|
+
@character_sheet.add(@path)
|
36
29
|
@character_sheet.save
|
37
|
-
|
38
|
-
|
39
|
-
@character_sheet.should have_received(:border_width=).with(20)
|
40
|
-
@character_sheet.should have_received(:border_color=).with("#ffffff")
|
41
|
-
@character_sheet.should have_received(:fill=).with("#000000")
|
42
|
-
@character_sheet.should have_received(:geometry=).with("150x150+10+5")
|
43
|
-
@character_sheet.should have_received(:matte_color=).with("#ffffff")
|
44
|
-
@character_sheet.should have_received(:title=).with('sheet')
|
45
|
-
|
46
|
-
image.should have_received(:write).with('/tmp/sheet_characters.png')
|
30
|
+
File.exists?('/tmp/sheet_characters.png').should be_true
|
31
|
+
File.delete('/tmp/sheet_characters.png')
|
47
32
|
end
|
48
33
|
end
|
49
|
-
end
|
34
|
+
end
|
@@ -1,5 +1,73 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hieroglyph::Font do
|
4
|
-
|
5
|
-
|
4
|
+
context 'A Font' do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
|
8
|
+
module Hieroglyph
|
9
|
+
def self.log(*)
|
10
|
+
end
|
11
|
+
def self.header(*)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
system('rm -rf /tmp/glyphs/')
|
16
|
+
system('mkdir /tmp/glyphs/')
|
17
|
+
path_to_test = File.expand_path('../../../support/test.svg', __FILE__)
|
18
|
+
system("cp #{path_to_test} /tmp/glyphs/a-test.svg")
|
19
|
+
@font = Hieroglyph::Font.new({:output_folder => '/tmp', :name => 'font', :glyph_folder => '/tmp/glyphs'})
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'includes files from assets' do
|
24
|
+
@font.include('header')
|
25
|
+
@font.contents.include?('xml').should eql true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'deletes existing SVG' do
|
29
|
+
@path = File.expand_path('/tmp/font.svg')
|
30
|
+
system ('touch /tmp/font.svg')
|
31
|
+
File.exists?(@path).should eql true
|
32
|
+
@font.setup()
|
33
|
+
File.exists?(@path).should eql false
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'creates a character sheet' do
|
37
|
+
@font.character_sheet = nil
|
38
|
+
@font.character_sheet.instance_of?(Hieroglyph::CharacterSheet).should eql false
|
39
|
+
@font.setup()
|
40
|
+
@font.character_sheet.instance_of?(Hieroglyph::CharacterSheet).should eql true
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'replaces name token in contents' do
|
44
|
+
@font.contents = 'xxx{{NAME}}xxx'
|
45
|
+
@font.contents = 'xxx{{NAME}}xxx'
|
46
|
+
@font.options[:name] = 'foo'
|
47
|
+
@font.set_name
|
48
|
+
@font.contents.should eql 'xxxfooxxx'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'writes a file' do
|
52
|
+
@path = '/tmp/font.svg'
|
53
|
+
system("rm #{@path}")
|
54
|
+
File.exists?(@path).should eql false
|
55
|
+
@font.output_path = @path
|
56
|
+
@font.finish
|
57
|
+
File.exists?(@path).should eql true
|
58
|
+
File.delete(@path)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'adds to contents' do
|
62
|
+
@font.contents = 'foo'
|
63
|
+
@font.add('bar')
|
64
|
+
@font.contents.should eql 'foobar'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'adds glyphs' do
|
68
|
+
@font.character_sheet.should_receive(:add)
|
69
|
+
@font.add_glyphs
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|