alpacabuildtool 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/.gitignore +48 -0
- data/.rubocop.yml +12 -0
- data/.semver +6 -0
- data/.travis.yml +10 -0
- data/CHANGELOG +18 -0
- data/Gemfile +7 -0
- data/LICENSE +22 -0
- data/README.md +235 -0
- data/README.rdoc +39 -0
- data/Rakefile +74 -0
- data/alpacabuildtool.gemspec +34 -0
- data/alpacabuildtool.rdoc +5 -0
- data/alpacabuildtool.todo +9 -0
- data/bin/alpaca +142 -0
- data/features/alpaca.feature +8 -0
- data/features/step_definitions/alpaca_steps.rb +13 -0
- data/features/step_definitions/visual_studio_solutions_steps.rb +47 -0
- data/features/support/env.rb +10 -0
- data/features/visual_studio_solutions.feature +43 -0
- data/lib/alpacabuildtool.rb +4 -0
- data/lib/alpacabuildtool/application.rb +195 -0
- data/lib/alpacabuildtool/configuration.rb +209 -0
- data/lib/alpacabuildtool/data/.alpaca.conf +148 -0
- data/lib/alpacabuildtool/data/doom.flf +826 -0
- data/lib/alpacabuildtool/data/logo.jpg +0 -0
- data/lib/alpacabuildtool/entities/nuspec.rb +107 -0
- data/lib/alpacabuildtool/entities/project.rb +54 -0
- data/lib/alpacabuildtool/entities/solution.rb +104 -0
- data/lib/alpacabuildtool/entities/xml.rb +41 -0
- data/lib/alpacabuildtool/entities/xml_node.rb +75 -0
- data/lib/alpacabuildtool/log/font.rb +92 -0
- data/lib/alpacabuildtool/log/log.rb +15 -0
- data/lib/alpacabuildtool/log/rainbowify_formatter.rb +70 -0
- data/lib/alpacabuildtool/log/rainbowify_logger.rb +47 -0
- data/lib/alpacabuildtool/managers/build_manager.rb +32 -0
- data/lib/alpacabuildtool/managers/package_manager.rb +136 -0
- data/lib/alpacabuildtool/managers/report_manager.rb +33 -0
- data/lib/alpacabuildtool/managers/test_manager.rb +35 -0
- data/lib/alpacabuildtool/os.rb +29 -0
- data/lib/alpacabuildtool/package_types/project_package.rb +44 -0
- data/lib/alpacabuildtool/package_types/tool_package.rb +53 -0
- data/lib/alpacabuildtool/tools/git.rb +22 -0
- data/lib/alpacabuildtool/tools/msbuild.rb +29 -0
- data/lib/alpacabuildtool/tools/nuget.rb +49 -0
- data/lib/alpacabuildtool/tools/nunit.rb +28 -0
- data/lib/alpacabuildtool/tools/nunit_orange.rb +18 -0
- data/lib/alpacabuildtool/tools/open_cover.rb +29 -0
- data/lib/alpacabuildtool/tools/report_generator.rb +25 -0
- data/lib/alpacabuildtool/tools/tool.rb +84 -0
- data/lib/alpacabuildtool/tools/wrapper.rb +66 -0
- data/lib/alpacabuildtool/versioning/version.rb +163 -0
- data/lib/alpacabuildtool/versioning/versioning.rb +84 -0
- data/spec/lib/alpacabuildtool/configuration_spec.rb +201 -0
- data/spec/lib/alpacabuildtool/entities/xml_spec.rb +39 -0
- data/spec/lib/alpacabuildtool/versioning/version_spec.rb +86 -0
- data/spec/lib/alpacabuildtool/versioning/versioning_spec.rb +194 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/coverage.rb +26 -0
- data/test_data/sln1/.alpaca.conf +11 -0
- data/test_data/sln1/.semver +6 -0
- data/test_data/sln1/TestSolution.sln +22 -0
- data/test_data/sln1/TestSolution/App.config +6 -0
- data/test_data/sln1/TestSolution/Program.cs +16 -0
- data/test_data/sln1/TestSolution/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln1/TestSolution/TestSolution.csproj +59 -0
- data/test_data/sln2/.alpaca.conf +8 -0
- data/test_data/sln2/.semver +6 -0
- data/test_data/sln2/ProjectName/ProjectName.csproj +54 -0
- data/test_data/sln2/ProjectName/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln2/ProjectName/SomeFolderInProject/SomeClass.cs +16 -0
- data/test_data/sln2/ProjectName2/ProjectName2.csproj +58 -0
- data/test_data/sln2/ProjectName2/Properties/AssemblyInfo.cs +37 -0
- data/test_data/sln2/SolutionName.sln +34 -0
- data/test_data/sln2/Unit.Tests/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln2/Unit.Tests/SomeClassTests.cs +21 -0
- data/test_data/sln2/Unit.Tests/Unit.Tests.csproj +65 -0
- data/test_data/sln2/Unit.Tests/packages.config +4 -0
- data/test_data/sln3/TestSolution.nobuild.sln +22 -0
- data/test_data/sln3/TestSolution/App.config +6 -0
- data/test_data/sln3/TestSolution/Program.cs +16 -0
- data/test_data/sln3/TestSolution/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln3/TestSolution/TestSolution.nobuild.csproj +59 -0
- metadata +309 -0
|
Binary file
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require 'alpacabuildtool/entities/xml'
|
|
2
|
+
|
|
3
|
+
module AlpacaBuildTool
|
|
4
|
+
##
|
|
5
|
+
# Nuspec creates *.nuspec file content
|
|
6
|
+
#
|
|
7
|
+
# Nuspec.new(id: 'Cool.Package',
|
|
8
|
+
# version: '0.0.1',
|
|
9
|
+
# description: 'something',
|
|
10
|
+
# authors: ['Vasyl', 'Kate'],
|
|
11
|
+
# false).to_s
|
|
12
|
+
# # => <?xml version="1.0"?>
|
|
13
|
+
# # <package>
|
|
14
|
+
# # <metadata>
|
|
15
|
+
# # <id>Cool.Package</id>
|
|
16
|
+
# # <version>0.0.1</version>
|
|
17
|
+
# # <authors>Vasyl,Kate</authors>
|
|
18
|
+
# # <description>something</description>
|
|
19
|
+
# # </metadata>
|
|
20
|
+
# # </package>
|
|
21
|
+
class Nuspec
|
|
22
|
+
OPTIONAL = %w(title licenseUrl projectUrl copyright iconUrl
|
|
23
|
+
requireLicenseAcceptance releaseNotes)
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Creates instance and generate content from *package* config
|
|
27
|
+
#
|
|
28
|
+
# +package+:: package configuration
|
|
29
|
+
# +add_common_files+:: flag to add files like README and CHANGELOG
|
|
30
|
+
def initialize(package, add_common_files = true)
|
|
31
|
+
@content = generate(package, add_common_files)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Overrides to_s method to create string content from inner Xml object
|
|
36
|
+
def to_s
|
|
37
|
+
@content.to_s
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Returns Xml object representation of package nuspec
|
|
42
|
+
#
|
|
43
|
+
# +config+:: package configuration
|
|
44
|
+
# +add_common_files+:: flag to add common files or not
|
|
45
|
+
def generate(config, add_common_files)
|
|
46
|
+
Xml.new '1.0' do
|
|
47
|
+
node 'package' do |package|
|
|
48
|
+
Nuspec.add_metadata(package, config)
|
|
49
|
+
Nuspec.add_files(package, config) if add_common_files
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# Adds metadata entry to nuspec
|
|
56
|
+
#
|
|
57
|
+
# +package+:: XmlNode where to add metadata
|
|
58
|
+
# +config+:: package configuration
|
|
59
|
+
def self.add_metadata(package, config)
|
|
60
|
+
package.node 'metadata' do |metadata|
|
|
61
|
+
Nuspec.add_mandatory_fields(metadata, config)
|
|
62
|
+
Nuspec.add_optional_fields(metadata, config)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
# Adds mandatory entries to nuspec like id, version, authors and description
|
|
68
|
+
#
|
|
69
|
+
# +metadata+:: XmlNode where to add entries
|
|
70
|
+
# +config+:: package configuration
|
|
71
|
+
def self.add_mandatory_fields(metadata, config)
|
|
72
|
+
metadata.node 'id', config['id']
|
|
73
|
+
metadata.node 'version', config['version']
|
|
74
|
+
metadata.node 'authors', config['authors'].join(',')
|
|
75
|
+
metadata.node 'description', config['description']
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# Adds optional entries to nuspec like owners, tags and so on
|
|
80
|
+
#
|
|
81
|
+
# +metadata+:: XmlNode where to add entries
|
|
82
|
+
# +config+:: package configuration
|
|
83
|
+
def self.add_optional_fields(metadata, config)
|
|
84
|
+
OPTIONAL.each { |name| metadata.node(name, config[name]) if config[name] }
|
|
85
|
+
metadata.node 'owners', config['owners'].join(',') if config['owners']
|
|
86
|
+
metadata.node 'tags', config['tags'].join(' ') if config['tags']
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# Adds README.txt and CHANGES.txt files
|
|
91
|
+
#
|
|
92
|
+
# +package+:: XmlNode where to add files entry
|
|
93
|
+
# +config+:: package configuration
|
|
94
|
+
def self.add_files(package, config)
|
|
95
|
+
package.node 'files' do
|
|
96
|
+
node 'file' do
|
|
97
|
+
attribute 'src', 'README.txt'
|
|
98
|
+
attribute 'target', ''
|
|
99
|
+
end if config['readme']
|
|
100
|
+
node 'file' do
|
|
101
|
+
attribute 'src', 'CHANGES.txt'
|
|
102
|
+
attribute 'target', ''
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module AlpacaBuildTool
|
|
2
|
+
##
|
|
3
|
+
# VisualStudioProject provides project representation and methods
|
|
4
|
+
# to modify it's AssemblyVersion.cs file
|
|
5
|
+
class Project
|
|
6
|
+
attr_accessor :name, :file, :dir
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# Creates instance of class
|
|
10
|
+
#
|
|
11
|
+
# +line+:: line from .sln file with project information
|
|
12
|
+
# +dir+:: solution directory
|
|
13
|
+
#
|
|
14
|
+
# s = AlpacaBuildTool::VisualStudioProject.new(
|
|
15
|
+
# 'Project("{FAE04EC0...5254043711}"'
|
|
16
|
+
# 'd:\')
|
|
17
|
+
# # => #<**:VisualStudioProject:** @file="d:/sln1/some.csproj" **>
|
|
18
|
+
def initialize(line, dir)
|
|
19
|
+
items = line.gsub(/".*?"/).to_a
|
|
20
|
+
_, @name, file, _ = items.map { |item| item.to_s.gsub('"', '') }
|
|
21
|
+
dir = File.expand_path(dir)
|
|
22
|
+
@dir = File.dirname(File.join(dir, file))
|
|
23
|
+
@file = File.join(dir, file)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Overrides *to_s* method to provide nice convertion to string
|
|
28
|
+
def to_s
|
|
29
|
+
"{#{@name};#{@file}}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Updates AssemblyInfo.cs file under the project with new_version
|
|
34
|
+
#
|
|
35
|
+
# +new_version+:: version that need to be used as assembly version
|
|
36
|
+
# and assembly file version
|
|
37
|
+
def update_version(new_version)
|
|
38
|
+
info_file = File.join(@dir, 'Properties', 'AssemblyInfo.cs')
|
|
39
|
+
content = IO.readlines(info_file)
|
|
40
|
+
open(info_file, 'w') do |io|
|
|
41
|
+
content.each { |line| io.write replace_version(line, new_version) }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def replace_version(line, new_version)
|
|
48
|
+
line = line.gsub(/AssemblyVersion\("(.*?)"\)/,
|
|
49
|
+
"AssemblyVersion(\"#{new_version}\")")
|
|
50
|
+
line.gsub(/AssemblyFileVersion\("(.*?)"\)/,
|
|
51
|
+
"AssemblyFileVersion(\"#{new_version}\")")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'alpacabuildtool/log/log'
|
|
2
|
+
require 'alpacabuildtool/configuration'
|
|
3
|
+
require 'alpacabuildtool/entities/project'
|
|
4
|
+
require 'alpacabuildtool/versioning/versioning'
|
|
5
|
+
|
|
6
|
+
module AlpacaBuildTool
|
|
7
|
+
##
|
|
8
|
+
# Solution provides solution representation and it's configuration storage
|
|
9
|
+
class Solution
|
|
10
|
+
include Log
|
|
11
|
+
|
|
12
|
+
attr_reader :file, :dir, :projects
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Creates instance from *.sln file
|
|
16
|
+
# Initializes solution's semantic version and absolute path to it's file
|
|
17
|
+
#
|
|
18
|
+
# +file+:: absolute or relative path to *.sln file
|
|
19
|
+
def initialize(file)
|
|
20
|
+
@file = File.expand_path(file)
|
|
21
|
+
@dir = File.dirname(@file)
|
|
22
|
+
@semver = Versioning.find(@dir)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Overrides string representation. Spawned to multiple lines
|
|
27
|
+
def to_s
|
|
28
|
+
s = '------------'
|
|
29
|
+
s += "\nFile: #{@file}"
|
|
30
|
+
s += "\nVersion: #{build_version}"
|
|
31
|
+
s += "\nProjects:" unless projects.empty?
|
|
32
|
+
projects.each { |p| s += "\n\t#{p}" }
|
|
33
|
+
s + "\n------------"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Returns Configuration object for current solution (initialized only once)
|
|
38
|
+
def configuration
|
|
39
|
+
@configuration ||= Configuration.new(self)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# Returns array of it's projects (initialized only once)
|
|
44
|
+
def projects
|
|
45
|
+
return @projects if @projects
|
|
46
|
+
@projects = []
|
|
47
|
+
IO.readlines(@file).each do |line|
|
|
48
|
+
@projects << Project.new(line, @dir) if /^Project.*\.csproj/ =~ line
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# Returns specific project by it's name
|
|
54
|
+
#
|
|
55
|
+
# +name+:: project's name
|
|
56
|
+
def project(name)
|
|
57
|
+
@projects.find { |p| p.name == name }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
##
|
|
61
|
+
# Updates all projects AssemblyInfo.cs files with specific version
|
|
62
|
+
#
|
|
63
|
+
# +version+:: version to be stored in AssemblyInfo.cs files
|
|
64
|
+
def update_projects_version(version)
|
|
65
|
+
projects.each do |project|
|
|
66
|
+
project.update_version version
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Returns array of projects that correspondes to specific type
|
|
72
|
+
#
|
|
73
|
+
# +type+:: type of project defined in configuration project_types
|
|
74
|
+
def specific_projects(type)
|
|
75
|
+
types = configuration['project_types'].dup
|
|
76
|
+
types.select! { |t| t['type'] == type } unless type == 'all'
|
|
77
|
+
projects.select do |project|
|
|
78
|
+
types.any? { |t| project.name.include? t['name'] }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Returns true if solution is marked as *nobuild*
|
|
84
|
+
def no_build?
|
|
85
|
+
solution_name = File.basename(@file, '.*')
|
|
86
|
+
(configuration['no_build'] || []).each do |tag|
|
|
87
|
+
return true if solution_name.include?(tag)
|
|
88
|
+
end
|
|
89
|
+
false
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# Returns current build version
|
|
94
|
+
def build_version
|
|
95
|
+
@semver.to_s '%M.%m.%p'
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
##
|
|
99
|
+
# Returns current package version
|
|
100
|
+
def package_version
|
|
101
|
+
@semver.to_s '%M.%m.%p%s'
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'alpacabuildtool/entities/xml_node'
|
|
2
|
+
|
|
3
|
+
module AlpacaBuildTool
|
|
4
|
+
##
|
|
5
|
+
# Xml represents simple xml document with one root node
|
|
6
|
+
#
|
|
7
|
+
# doc = Xml.new '1.0' do
|
|
8
|
+
# node 'a', 'b'
|
|
9
|
+
# end
|
|
10
|
+
# doc.to_s
|
|
11
|
+
# # => <?xml version="1.0"?>
|
|
12
|
+
# # <a>b</a>
|
|
13
|
+
class Xml
|
|
14
|
+
##
|
|
15
|
+
# Creates instance
|
|
16
|
+
#
|
|
17
|
+
# +version+:: xml version
|
|
18
|
+
# accepts &block
|
|
19
|
+
def initialize(version, &block)
|
|
20
|
+
@version, @root_node = version, nil
|
|
21
|
+
instance_eval(&block) if block_given?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Set/override root node
|
|
26
|
+
#
|
|
27
|
+
# +name+:: node name
|
|
28
|
+
# +content+:: node content
|
|
29
|
+
# accepts &block
|
|
30
|
+
def node(name, content = nil, &block)
|
|
31
|
+
@root = XmlNode.new(name, content, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Overrides string representation to generate xml document content from
|
|
36
|
+
# stored objects
|
|
37
|
+
def to_s
|
|
38
|
+
"<?xml version=\"#{@version}\"?>\n#{@root}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
3
|
+
module AlpacaBuildTool
|
|
4
|
+
##
|
|
5
|
+
# XmlNode represents simple xml node that can contain attributes and other
|
|
6
|
+
# nodes or string as a content
|
|
7
|
+
class XmlNode
|
|
8
|
+
attr_reader :name, :content
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Creates an instance
|
|
12
|
+
#
|
|
13
|
+
# +name+:: name of node
|
|
14
|
+
# +content+:: content of node (if set, block is ignored)
|
|
15
|
+
# accepts &block to set content to array of nodes
|
|
16
|
+
def initialize(name, content = nil, &block)
|
|
17
|
+
@name = name
|
|
18
|
+
return @content = content unless content.nil?
|
|
19
|
+
return unless block_given?
|
|
20
|
+
@arity = block.arity
|
|
21
|
+
if @arity <= 0
|
|
22
|
+
@context = eval('self', block.binding)
|
|
23
|
+
instance_eval(&block)
|
|
24
|
+
else
|
|
25
|
+
yield self
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Adds new node into content
|
|
31
|
+
#
|
|
32
|
+
# +name+:: node name
|
|
33
|
+
# +content+:: node content
|
|
34
|
+
# accepts &block for this new node
|
|
35
|
+
#
|
|
36
|
+
# XmlNode.new 'a' do
|
|
37
|
+
# node 'b' do
|
|
38
|
+
# node 'c' do
|
|
39
|
+
# ...
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
# end
|
|
43
|
+
def node(name, content = nil, &block)
|
|
44
|
+
(@content ||= []) << XmlNode.new(name, content, &block)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# Adds attribute to node
|
|
49
|
+
#
|
|
50
|
+
# +name+:: attribute name
|
|
51
|
+
# +value+:: attribute value
|
|
52
|
+
def attribute(name, value)
|
|
53
|
+
(@attributes ||= {})[name] = value
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Overrides string representation to populate xml pretty formatted content
|
|
58
|
+
def to_s
|
|
59
|
+
return "<#{@name}#{attributes_to_s}/>" if @content.nil?
|
|
60
|
+
content = @content.is_a?(Array) ? array_to_s : CGI.escape_html(@content)
|
|
61
|
+
"<#{@name}#{attributes_to_s}>#{content}</#{@name}>"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def attributes_to_s
|
|
67
|
+
(@attributes || {}).map { |n, v| " #{n}=\"#{v}\"" }.reduce(&:+)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def array_to_s
|
|
71
|
+
nodes = @content.map { |n| "\t#{n}".gsub(/\n/, "\n\t") }
|
|
72
|
+
"\n#{nodes.join("\n")}\n"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module AlpacaBuildTool
|
|
2
|
+
##
|
|
3
|
+
# Font class provides representation of .flf fonts so they can be used
|
|
4
|
+
class Font
|
|
5
|
+
attr_reader :height, :hard_blank
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Absolute path to data folder where *.flf fonts stored
|
|
9
|
+
FONTPATH = File.expand_path(File.dirname(__FILE__) + '/../data')
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Creates instance of class
|
|
13
|
+
#
|
|
14
|
+
# +name+:: font name(currently 'doom' or 'lean' exist)
|
|
15
|
+
def initialize(name)
|
|
16
|
+
@filename = File.join FONTPATH, name + '.flf'
|
|
17
|
+
File.open(@filename, 'rb') do |f|
|
|
18
|
+
header = f.gets.strip.split(/ /)
|
|
19
|
+
@hard_blank = header[0]
|
|
20
|
+
@height = header[1].to_i
|
|
21
|
+
load_characters f
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Returns true if font have representation for char.ord
|
|
27
|
+
#
|
|
28
|
+
# +ord+:: character code(char.ord)
|
|
29
|
+
def char?(ord)
|
|
30
|
+
@characters.key? ord
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Returns array of lines that represent current character
|
|
35
|
+
#
|
|
36
|
+
# +ord+:: character code(char.ord)
|
|
37
|
+
def [](ord)
|
|
38
|
+
@characters[ord]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def load_characters(file)
|
|
44
|
+
@characters = {}
|
|
45
|
+
load_ascii_characters file
|
|
46
|
+
load_german_characters file
|
|
47
|
+
load_extended_characters file
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def load_ascii_characters(file)
|
|
51
|
+
(32..126).each { |i| @characters[i] = load_char(file) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def load_german_characters(file)
|
|
55
|
+
[91, 92, 93, 123, 124, 125, 126].each do |i|
|
|
56
|
+
char = load_char(file)
|
|
57
|
+
break unless char
|
|
58
|
+
@characters[i] = char
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def load_extended_characters(file)
|
|
63
|
+
until file.eof?
|
|
64
|
+
i = file.gets.strip.split(/ /).first
|
|
65
|
+
if i && i.empty?
|
|
66
|
+
next
|
|
67
|
+
else
|
|
68
|
+
char = load_char(file)
|
|
69
|
+
return unless char
|
|
70
|
+
@characters[i] = char
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def load_char(file)
|
|
76
|
+
char = []
|
|
77
|
+
@height.times do
|
|
78
|
+
return false if file.eof?
|
|
79
|
+
char << load_line(file)
|
|
80
|
+
end
|
|
81
|
+
char
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def load_line(file)
|
|
85
|
+
line = file.gets.rstrip
|
|
86
|
+
match = /(.){1,2}$/.match(line)
|
|
87
|
+
line.gsub!(match[1], '') if match
|
|
88
|
+
line << "\x00"
|
|
89
|
+
line
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|