Repository navigation
Expand file tree
/
Copy pathRakefile
More file actions
163 lines (142 loc) · 4.34 KB
/
Copy pathRakefile
File metadata and controls
163 lines (142 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Copyright 2011-2014 Brent Rowland.
# Use of this source code is governed the Apache License, Version 2.0, as described in the LICENSE file.
require 'iconv'
codepages = %w(
ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-6 ISO-8859-7 ISO-8859-8 ISO-8859-9
ISO-8859-10 ISO-8859-11 ISO-8859-13 ISO-8859-14 ISO-8859-15 ISO-8859-16
CP1252 CP1250 CP1251 CP1253 CP1254 CP1256 CP1257 CP1258 CP874)
codepages.each do |cp|
desc "Generate codepage table for #{cp}"
task cp do
generate_codepage_table(cp)
end
desc "Generate codepage map for #{cp}"
task "#{cp}_map" do
generate_codepage_map(cp)
end
end
task :maps => codepages.map { |cp| "#{cp}_map" }
# task :default => codepages + [:cpselect]
def generate_codepage_table(cp)
puts "Generating codepage table for #{cp}"
ranges = codepage_table(cp)
open(cp.downcase+".go", "w") do |f|
f.puts "package codepage", ""
f.puts "var #{cp.gsub('-', '_')} = Codepage{"
ranges.each do |range|
f.puts "\t{0x%04X, 0x%04X, %d, %d}," % [range.first, range.first + range.count - 1, range.count, range.delta]
end
f.puts "}"
end
end
def codepage_table(cp)
codepoints = Iconv.open("UCS-2BE//IGNORE", cp) do |ic|
(0..255).map { |c| ic.iconv(c.chr) }.map { |s| s.unpack('n') }.map { |a| a.first }
end
ranges_from_ary(codepoints, cp).sort! { |a, b| a.first <=> b.first }
end
def codepage_map(cp)
Iconv.open("UCS-2BE//IGNORE", cp) do |ic|
(0..255).map { |c| ic.iconv(c.chr) }.map { |s| s.unpack('n') }.map { |a| a.first }
end
end
def generate_codepage_map(cp)
puts "Generating codepage map for #{cp}"
map = codepage_map(cp)
open(cp.downcase+"_map.go", "w") do |f|
f.puts "// Copyright 2014 Brent Rowland."
f.puts "// Use of this source code is governed the Apache License, Version 2.0, as described in the LICENSE file."
f.puts
f.puts "package codepage", ""
f.puts "var #{cp.gsub('-', '_')}_Map = []rune{"
map.each_with_index do |r, i|
f.puts "\t0x%04X, // #{i}" % [r, i]
end
f.puts "}"
end
end
CPRange = Struct.new(:first, :count, :delta, :codepage)
class CPRanges < Array
attr_accessor :name
def char_for_codepoint(cp)
low, high = 0, self.size - 1
while low <= high
i = (low + high) / 2
r = self[i]
if cp < r.first
high = i - 1
next
end
if cp >= r.first + r.count
low = i + 1
next
end
return cp + r.delta
end
return nil
end
end
def ranges_from_ary(codepoints, name)
ranges = CPRanges.new
ranges.name = name
range = nil
last_codepoint = 0
codepoints.each_with_index do |codepoint, i|
next if codepoint.nil?
if range.nil? or (codepoint != last_codepoint + 1)
range = CPRange.new(codepoint, 1, i - codepoint)
ranges << range
else
range.count += 1
end
last_codepoint = codepoint
end
ranges
end
class Codepages < Array
def codepage_for_codepoint(cp)
self.size.times do |i|
if ch = self[i].char_for_codepoint(cp)
# puts "#{cp}: #{ch}, #{self[i].name}"
return self[i].name
end
end
nil
end
end
desc "Generate codepage selection table"
task :cpselect do
tables = Codepages.new.replace(codepages.map { |cp| codepage_table(cp) })
codepoint_codepages = (0..0x2122).map { |cp| tables.codepage_for_codepoint(cp) }
# codepoint_codepages.each_with_index { |codepage, codepoint| puts "#{codepoint}: #{codepage.inspect}" }
ranges = []
range = nil
last_codepage = 0
codepoint_codepages.each_with_index do |codepage, codepoint|
next if codepage.nil?
if range.nil? or (codepage != last_codepage)
range = CPRange.new(codepoint, 1, nil, codepage)
ranges << range
else
range.count += 1
end
last_codepage = codepage
end
open("cpselect.go", "w") do |f|
f.puts "package codepage", ""
f.puts "const ("
codepages.each_with_index do |cp, i|
f.puts "\tidx_%s%s"% [cp.gsub('-', '_'), i == 0 ? " = iota" : ""]
end
f.puts ")"
f.puts
f.puts "var CodepointCodepages = CodepageRanges{"
ranges.each do |range|
f.puts "\t{0x%04X, 0x%04X, %d, %s}," % [range.first, range.first + range.count - 1, range.count, "idx_" + range.codepage.gsub('-', '_')]
end
f.puts "}", ""
f.puts "var Codepages = []Codepage{"
codepages.each { |cp| f.puts "\t%s," % cp.gsub('-', '_') }
f.puts "}"
end
end