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.
@@ -5,5 +5,3 @@
5
5
  <font id="{{NAME}}" horiz-adv-x="1024" >
6
6
  <font-face units-per-em="1024" ascent="819" descent="-205" />
7
7
  <missing-glyph horiz-adv-x="500" />
8
- <glyph d="M0 0h1000v1024h-1000v-1024z" />
9
- <glyph d="M0 0h1000v1024h-1000v-1024z" />
@@ -1,48 +1,40 @@
1
1
  module Hieroglyph
2
2
 
3
- if rmagick_installed?
4
- class CharacterSheet
3
+ class CharacterSheet
5
4
 
6
- def initialize(options)
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
- def add(file, name)
17
- character = Magick::Image::read(file).first
18
- character['Label'] = name
19
- @characters.push character
20
- end
7
+ @@montage_args = {
8
+ 'background' => '#ffffff',
9
+ 'fill' => '#000000',
10
+ 'geometry' => '150x150+25+25',
11
+ 'label' => '%t',
12
+ 'mattecolor' => '#ffffff'
13
+ }
21
14
 
22
- def save
23
- name = @options[:name]
24
- img = @characters.montage do
25
- self.background_color = "#ffffff"
26
- self.border_width = 20
27
- self.border_color = "#ffffff"
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
- else
38
- # No-op
39
- class CharacterSheet
40
- def initialize(*)
41
- end
42
- def add(file, name)
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
- def save
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.log "", " Saved to #{@options[:output_folder]}", "", "=== #{@options[:name]} generated ===", ""
23
- Hieroglyph.log "To create a full set of webfonts, upload to:", "http://www.fontsquirrel.com/fontface/generator", ""
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
 
@@ -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 add_header
15
- header_path = File.join(File.dirname(__FILE__), "assets/header")
16
- header = File.open(header_path).read
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.log "", "=== Generating #{@options[:name]} ===", ""
29
- if File.exist? @output_path
30
- Hieroglyph.log " #{@output_path} exists, deleting"
31
- File.delete @output_path
32
- end
33
- @character_sheet = CharacterSheet.new(@options)
34
- add_header
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
- add_footer
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 "", " Reading from #{@options[:glyph_folder]}...", ""
52
- Dir.glob(File.join(@options[:glyph_folder], "*.svg")).each do |file|
53
- glyph = Glyph.new(file, @options[:glyph_folder])
54
- @character_sheet.add(file, glyph.name)
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
@@ -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
- def initialize(file, source)
11
- @name = file.gsub(source, "").gsub("/", "").each_char.first
12
- Hieroglyph.log " #{@name} -> reading..."
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
- @polygon = @contents.root.at_css("polygon")
15
- @path = @polygon.nil? ? convert_path: convert_polygon
16
- flip_paths
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 flip_paths
20
- @path.subpaths.each do |subpath|
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
- end
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
- return "<glyph unicode=\"#{@name}\" d=\"#{@path.to_command}\" />\n"
143
+ @path ? "<glyph unicode=\"#{@name}\" d=\"#{@path.to_command}\" />\n" : ''
86
144
  end
87
145
 
88
146
  end
@@ -0,0 +1,13 @@
1
+ module Hieroglyph
2
+
3
+ class NoopSheet
4
+ def initialize(*)
5
+ Hieroglyph.log "ImageMagick not detected - skipping character sheet"
6
+ end
7
+ def add(file)
8
+ end
9
+ def save
10
+ end
11
+ end
12
+
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Hieroglyph
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
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 "A CharacterSheet" do
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 "adds a file with a given name" do
13
- character = stub(:[]=)
14
- Magick::Image.stubs(:read).returns([character])
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
- Magick::Image.should have_received(:read).with('a file')
19
- character.should have_received(:[]=).with('Label', 'some name')
20
- @characters.should have_received(:push).with(character)
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
- image = stub(:write)
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
- @character_sheet.should have_received(:background_color=).with("#ffffff")
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
- end
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