hyogen 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +5 -2
- data/README +47 -0
- data/Rakefile +20 -2
- data/bin/hyogen +26 -0
- data/lib/hyogen/reader.rb +288 -0
- data/lib/hyogen/table_elements.rb +38 -0
- data/lib/hyogen/template.rb +17 -0
- data/lib/hyogen/version.rb +1 -1
- data/spec/spec_hyogen.rb +20 -20
- metadata +9 -7
- data/spec/spec_hyogen.rb.1~ +0 -294
- data/test/test_helper.rb +0 -2
- data/test/test_hyogen.rb +0 -11
data/Manifest.txt
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
History.txt
|
2
2
|
Manifest.txt
|
3
3
|
README.txt
|
4
|
+
README
|
4
5
|
Rakefile
|
6
|
+
bin/hyogen
|
5
7
|
lib/hyogen.rb
|
8
|
+
lib/hyogen/reader.rb
|
9
|
+
lib/hyogen/table_elements.rb
|
10
|
+
lib/hyogen/template.rb
|
6
11
|
lib/hyogen/version.rb
|
7
12
|
scripts/txt2html
|
8
13
|
setup.rb
|
9
|
-
test/test_helper.rb
|
10
|
-
test/test_hyogen.rb
|
11
14
|
website/index.html
|
12
15
|
website/index.txt
|
13
16
|
website/javascripts/rounded_corners_lite.inc.js
|
data/README
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
= Overview
|
2
|
+
Hyogen converts CSV or Excel data to Ruby objects or any text.
|
3
|
+
This package is like Java's XLSBeans library.
|
4
|
+
|
5
|
+
= Here is how do you it
|
6
|
+
|
7
|
+
Start with a very simple example.
|
8
|
+
|
9
|
+
=== Input
|
10
|
+
|
11
|
+
Input data is CSV or Excel format data. The data have to include table tag.
|
12
|
+
Hyogen converts input data to array of Table class object.
|
13
|
+
Table class is set of Record class. Record class is a row of table.
|
14
|
+
|
15
|
+
{VTABLE}User List
|
16
|
+
{L}id, name, gender
|
17
|
+
1, Taro, male
|
18
|
+
2, Hanko, female
|
19
|
+
3, Ichiro, male
|
20
|
+
|
21
|
+
=== Template
|
22
|
+
|
23
|
+
Template format is erb.
|
24
|
+
|
25
|
+
<%- table = tables.first -%>
|
26
|
+
<%- for record in table.records -%>
|
27
|
+
My name is <%= record["name"] %>. I'm <%= record["gender"] %>.
|
28
|
+
<%- end -%>
|
29
|
+
|
30
|
+
=== Output
|
31
|
+
|
32
|
+
My name is Taro. I'm male.
|
33
|
+
My name is Hanko. I'm female.
|
34
|
+
My name is Ichiro. I'm male.
|
35
|
+
|
36
|
+
= Table tag
|
37
|
+
|
38
|
+
<b>{VTABLE}</b>:: This tag means start of table and the line of records is vertical.
|
39
|
+
<b>{HTABLE}</b>:: This tag means start of table and the line of records is horizontal.
|
40
|
+
<b>{L}</b>:: This tag means start of label.
|
41
|
+
|
42
|
+
<b>{N}</b>:: This tag means
|
43
|
+
<b><></b>:: This tag means
|
44
|
+
|
45
|
+
= Install
|
46
|
+
require ParseExcel
|
47
|
+
|
data/Rakefile
CHANGED
@@ -45,8 +45,8 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
|
45
45
|
p.url = HOMEPATH
|
46
46
|
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
47
47
|
# p.test_globs = ["test/**/test_*.rb"]
|
48
|
-
# p.test_globs = ["spec/**/spec_*.rb"]
|
49
|
-
p.test_globs = ["spec/**/*"]
|
48
|
+
# p.test_globs = ["spec/**/spec_*.rb", "spec/**/*.csv", "spec/**/*.xls"]
|
49
|
+
p.test_globs = ["spec/**/*[^~]"]
|
50
50
|
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
51
51
|
# p.package_files.include("spec/**/*")
|
52
52
|
|
@@ -96,3 +96,21 @@ task :check_version do
|
|
96
96
|
exit
|
97
97
|
end
|
98
98
|
end
|
99
|
+
|
100
|
+
Rake::RDocTask.new do |rdoc|
|
101
|
+
rdoc.rdoc_dir = 'html'
|
102
|
+
rdoc.options += RDOC_OPTS
|
103
|
+
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
104
|
+
if ENV['DOC_FILES']
|
105
|
+
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
|
106
|
+
else
|
107
|
+
# rdoc.rdoc_files.include('README', 'CHANGELOG')
|
108
|
+
rdoc.rdoc_files.include('README')
|
109
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
desc "Publish to RubyForge"
|
114
|
+
task :rubyforge => [:rdoc, :package] do
|
115
|
+
Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'yyagi').upload
|
116
|
+
end
|
data/bin/hyogen
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/bin/ruby
|
2
|
+
|
3
|
+
require 'lib/hyogen'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
opts = OptionParser.new do |opt|
|
7
|
+
opt.on("-s source") {|val| $sourcefile = val}
|
8
|
+
opt.on("-o outputdir") {|val| $outputdir = val}
|
9
|
+
end
|
10
|
+
opts.parse! ARGV
|
11
|
+
$templatefiles = ARGV
|
12
|
+
$outputdir ||= '.'
|
13
|
+
|
14
|
+
if ([$sourcefile, $templatefiles].any? {|e| e == nil})
|
15
|
+
puts <<USAGE
|
16
|
+
Usage: #{$0} -s sourcefile [-o outputdir] templatefiles
|
17
|
+
sourcefile: csv or xls file
|
18
|
+
templatefiles: The extention of file name is '.template'.
|
19
|
+
USAGE
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
tables = Hyogen.parse_tables($sourcefile)
|
24
|
+
for template in $templatefiles do
|
25
|
+
Hyogen::Template.generate(tables, template, $outputdir)
|
26
|
+
end
|
@@ -0,0 +1,288 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'csv'
|
3
|
+
require 'parseexcel'
|
4
|
+
|
5
|
+
module Hyogen
|
6
|
+
class Reader
|
7
|
+
module Tag
|
8
|
+
VTABLE = /\{VTABLE\}/
|
9
|
+
HTABLE = /\{HTABLE\}/
|
10
|
+
LABELS = /\{L\}/
|
11
|
+
LABEL_NOTE = /\{N\}/
|
12
|
+
ALIAS = /<(.+)>/
|
13
|
+
|
14
|
+
def self.aliased(str)
|
15
|
+
result = remove_space( (str =~ Tag::ALIAS) ? $1 : str )
|
16
|
+
(result || "").sub(LABEL_NOTE,"")
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.lookup_tag(obj, tag)
|
20
|
+
return nil if obj == nil
|
21
|
+
list = (obj.kind_of?(Array) ? obj : [obj])
|
22
|
+
data = nil
|
23
|
+
position = nil
|
24
|
+
matched_value = nil
|
25
|
+
list.each_with_index do |value, i|
|
26
|
+
if tag =~ value
|
27
|
+
matched_value = value
|
28
|
+
position = i
|
29
|
+
m = Regexp.last_match
|
30
|
+
data = remove_space(m.pre_match)
|
31
|
+
data = remove_space(m.post_match) if data == ""
|
32
|
+
break
|
33
|
+
end
|
34
|
+
end
|
35
|
+
return nil unless matched_value
|
36
|
+
{:value => matched_value, :tag => tag, :data => data, :position => position}
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.lookup_table_tag(obj)
|
40
|
+
lookup_tag(obj, Tag::VTABLE) or lookup_tag(obj, Tag::HTABLE)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def self.remove_space(str)
|
45
|
+
return nil unless str
|
46
|
+
str.sub(/^\s*/,"").sub(/\s*$/,"")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Matrix
|
51
|
+
extend Forwardable
|
52
|
+
def initialize data
|
53
|
+
@data = data #���z��
|
54
|
+
end
|
55
|
+
def_delegator :@data, :each, :each_row
|
56
|
+
def_delegator :@data, :each_with_index, :each_row_with_index
|
57
|
+
def_delegator :@data, :[], :row
|
58
|
+
def_delegator :@data, :size, :row_size
|
59
|
+
def_delegators :@data, :first
|
60
|
+
def value(row, column) @data[row][column] end
|
61
|
+
def column_size(n=0) (@data == []) ? 0 : @data[n].size end
|
62
|
+
def column(n) @data.collect {|line| line[n]} end
|
63
|
+
def subset(row_range) self.class.new(row(row_range)) end
|
64
|
+
def to_a() row(0..-1) end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Scheme
|
68
|
+
private
|
69
|
+
class PositionedLabel
|
70
|
+
def initialize(aNames, aPosition)
|
71
|
+
@names = aNames #String[]
|
72
|
+
@position = aPosition
|
73
|
+
@note = {}
|
74
|
+
end
|
75
|
+
attr_reader :names, :position
|
76
|
+
attr_accessor :note
|
77
|
+
end
|
78
|
+
public
|
79
|
+
def initialize
|
80
|
+
@body_position = nil
|
81
|
+
@record_direction = nil
|
82
|
+
@record_position = nil
|
83
|
+
@record_size = nil
|
84
|
+
@positioned_labels = []
|
85
|
+
end
|
86
|
+
attr_reader :positioned_labels
|
87
|
+
attr_accessor :body_position, :record_direction, :record_position, :record_size
|
88
|
+
def add_label(label_name, position)
|
89
|
+
before_label = @positioned_labels.find{|l| l.position == position}
|
90
|
+
if before_label
|
91
|
+
before_label.names << label_name
|
92
|
+
else
|
93
|
+
@positioned_labels << PositionedLabel.new([label_name], position)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
def positioned_labels_to_labels
|
97
|
+
@positioned_labels.collect {|pos_label| Label.new(pos_label.names, pos_label.note)}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def initialize matrix
|
102
|
+
@source = matrix
|
103
|
+
@table = nil
|
104
|
+
@scheme = nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def read_table
|
108
|
+
return nil unless Tag::lookup_table_tag(@source.first)
|
109
|
+
|
110
|
+
@scheme = Scheme.new
|
111
|
+
title = read_table_header
|
112
|
+
@table = Table.new(title)
|
113
|
+
read_labels
|
114
|
+
@table.records = read_records
|
115
|
+
@table.labels = @scheme.positioned_labels_to_labels
|
116
|
+
@table
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
def read_table_header
|
121
|
+
table_tag = Tag::lookup_table_tag(@source.first)
|
122
|
+
raise "is not table" unless table_tag
|
123
|
+
title = table_tag[:data]
|
124
|
+
@scheme.record_direction = (table_tag[:tag] == Tag::HTABLE ? :horizontal : :vertical)
|
125
|
+
@scheme.body_position = 1
|
126
|
+
title
|
127
|
+
end
|
128
|
+
|
129
|
+
def read_labels
|
130
|
+
@source.each_row_with_index do |values, row|
|
131
|
+
next if row < @scheme.body_position
|
132
|
+
values.each_with_index do |value, column|
|
133
|
+
read_labels_from value, row, column
|
134
|
+
end
|
135
|
+
# break unless @record_position[:row] == row
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def read_labels_from(value, row, column)
|
140
|
+
tagdata = Tag::lookup_tag(value, Tag::LABELS)
|
141
|
+
return unless tagdata
|
142
|
+
|
143
|
+
case @scheme.record_direction
|
144
|
+
when :vertical
|
145
|
+
@scheme.record_position = row + 1
|
146
|
+
@scheme.record_size = @source.column(column).size - @scheme.record_position
|
147
|
+
label_names = [tagdata[:data]] + @source.row(row)[column+1 .. -1]
|
148
|
+
label_start_position = column
|
149
|
+
|
150
|
+
when :horizontal
|
151
|
+
@scheme.record_position = column + 1
|
152
|
+
@scheme.record_size = @source.row(row).size - @scheme.record_position
|
153
|
+
label_names = [tagdata[:data]] + @source.column(column)[row+1 .. -1]
|
154
|
+
label_start_position = row
|
155
|
+
else
|
156
|
+
raise
|
157
|
+
end
|
158
|
+
add_label label_names, label_start_position
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_label label_names, label_start_position
|
162
|
+
@previous_label_name = nil
|
163
|
+
label_names.each_with_index do |label_name, i|
|
164
|
+
if label_name
|
165
|
+
label_name = Tag.aliased(label_name)
|
166
|
+
else
|
167
|
+
raise "���x����������܂���" unless @previous_label_name
|
168
|
+
label_name = @previous_label_name
|
169
|
+
end
|
170
|
+
@scheme.add_label label_name, label_start_position+i
|
171
|
+
@previous_label_name = label_name
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# def directed_values(position, start_pos, end_pos)
|
176
|
+
# end
|
177
|
+
|
178
|
+
def key_position_of_label
|
179
|
+
@scheme.positioned_labels.first.position
|
180
|
+
end
|
181
|
+
|
182
|
+
def read_records
|
183
|
+
return [] if [@source, @scheme, @scheme.record_position].any? {|e| e == nil}
|
184
|
+
record_last_position = @scheme.record_position + @scheme.record_size
|
185
|
+
(@scheme.record_position ... record_last_position).collect do |pos|
|
186
|
+
unless read_label_note_from pos
|
187
|
+
read_record_from pos
|
188
|
+
end
|
189
|
+
end.compact
|
190
|
+
rescue ArgumentError
|
191
|
+
return []
|
192
|
+
end
|
193
|
+
|
194
|
+
def read_label_note_from pos
|
195
|
+
note_tag = Tag::lookup_tag(read_value(key_position_of_label, pos), Tag::LABEL_NOTE)
|
196
|
+
return nil unless note_tag
|
197
|
+
note_name = Tag.aliased(note_tag[:data])
|
198
|
+
for pos_label in @scheme.positioned_labels do
|
199
|
+
value = Tag.aliased read_value(pos_label.position, pos)
|
200
|
+
pos_label.note[note_name] = value
|
201
|
+
end
|
202
|
+
true
|
203
|
+
end
|
204
|
+
|
205
|
+
def read_record_from pos
|
206
|
+
record = Record.new
|
207
|
+
for pos_label in @scheme.positioned_labels do
|
208
|
+
value = Tag.aliased read_value(pos_label.position, pos)
|
209
|
+
record.set pos_label.names, value
|
210
|
+
end
|
211
|
+
record
|
212
|
+
end
|
213
|
+
|
214
|
+
def read_value label_position, pos
|
215
|
+
(@scheme.record_direction == :vertical) ? @source.value(pos, label_position) : @source.value(label_position,pos)
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
def self.read_tables(any_format)
|
220
|
+
matrix_list = any_format_to_matrixies any_format
|
221
|
+
matrix_list.collect do |matrix|
|
222
|
+
Reader.devide_into_table(matrix).collect do |table_lines|
|
223
|
+
Reader.new(table_lines).read_table
|
224
|
+
end
|
225
|
+
end.flatten
|
226
|
+
end
|
227
|
+
|
228
|
+
def self.any_format_to_matrixies any_format
|
229
|
+
case any_format
|
230
|
+
when Array #Array of Array of Value
|
231
|
+
[ Matrix.new(any_format) ]
|
232
|
+
when String
|
233
|
+
case File.extname(any_format)
|
234
|
+
when '.csv'
|
235
|
+
[ Matrix.new(CSV.read(any_format)) ]
|
236
|
+
when '.xls'
|
237
|
+
matrixes_from_excel_file(any_format)
|
238
|
+
else #String of CSV
|
239
|
+
[ Matrix.new(CSV.parse(any_format)) ]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
CHAR_CODE = 'sjis'
|
245
|
+
def self.worksheet_to_matrix worksheet
|
246
|
+
data = []
|
247
|
+
worksheet.num_rows.times do |r|
|
248
|
+
data << worksheet.row(r).collect {|cell| cell.to_s(CHAR_CODE)}
|
249
|
+
end
|
250
|
+
Matrix.new(data)
|
251
|
+
end
|
252
|
+
|
253
|
+
def self.matrixes_from_excel_file(file_path)
|
254
|
+
result = []
|
255
|
+
workbook = Spreadsheet::ParseExcel.parse(file_path)
|
256
|
+
workbook.sheet_count.times do |sheet_num|
|
257
|
+
result << worksheet_to_matrix(workbook.worksheet(sheet_num))
|
258
|
+
end
|
259
|
+
result
|
260
|
+
end
|
261
|
+
|
262
|
+
def self.start_of_table(line)
|
263
|
+
Tag::lookup_table_tag(line) != nil
|
264
|
+
end
|
265
|
+
|
266
|
+
def self.end_of_table(line)
|
267
|
+
(line.all? {|v| v == nil or v =~ /^\s*$/}) or start_of_table(line)
|
268
|
+
end
|
269
|
+
|
270
|
+
public
|
271
|
+
def self.devide_into_table matrix
|
272
|
+
result = []
|
273
|
+
count = 0
|
274
|
+
until (count >= matrix.row_size) do
|
275
|
+
unless start_of_table( matrix.row(count) )
|
276
|
+
count += 1
|
277
|
+
next
|
278
|
+
end
|
279
|
+
start_of_table = count
|
280
|
+
|
281
|
+
begin count += 1 end until (count >= matrix.row_size or Tag::lookup_tag(matrix.row(count),Tag::LABELS))
|
282
|
+
count += 1 until (count >= matrix.row_size or end_of_table(matrix.row(count)) )
|
283
|
+
result << matrix.subset(start_of_table...count)
|
284
|
+
end
|
285
|
+
result
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Hyogen
|
2
|
+
#�\����ǂݎ�������R�[�h
|
3
|
+
#�\�̃��x�����������ƂȂ�A�\�̒l�������̒l�ƂȂ�B
|
4
|
+
class Record < Hash
|
5
|
+
def initialize
|
6
|
+
end
|
7
|
+
|
8
|
+
def set(label_names, value)
|
9
|
+
target = self
|
10
|
+
label_names.each_with_index do |name, i|
|
11
|
+
if (i+1) == label_names.size
|
12
|
+
target[name] = value
|
13
|
+
else
|
14
|
+
target[name] ||= {}
|
15
|
+
target = target[name]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Label
|
22
|
+
def initialize names, note
|
23
|
+
@names = names # Array of String
|
24
|
+
@note = note # (String, String)
|
25
|
+
end
|
26
|
+
attr_reader :names, :note
|
27
|
+
end
|
28
|
+
|
29
|
+
class Table
|
30
|
+
def initialize(title)
|
31
|
+
@title = title
|
32
|
+
@labels = nil
|
33
|
+
@records = nil
|
34
|
+
end
|
35
|
+
attr_reader :title
|
36
|
+
attr_accessor :labels, :records
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Hyogen
|
4
|
+
class Template
|
5
|
+
def self.generate(tables, source_path, output_dir='.')
|
6
|
+
@tables = tables
|
7
|
+
erb = File.open(source_path) {|f| ERB.new(f.read, nil, "-")}
|
8
|
+
result = erb.result(binding)
|
9
|
+
File.open(generate_file_name(output_dir,source_path), "w") {|f| f.write result}
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.generate_file_name(output_dir, source_path)
|
13
|
+
filename = File.basename(source_path, File.extname(source_path))
|
14
|
+
output_dir + '/' + filename
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/hyogen/version.rb
CHANGED
data/spec/spec_hyogen.rb
CHANGED
@@ -5,29 +5,29 @@ context "deviding csvlines into tables:" do
|
|
5
5
|
specify "empty" do
|
6
6
|
csvdata = CSV.parse("")
|
7
7
|
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
8
|
-
table_list.
|
8
|
+
table_list.should == []
|
9
9
|
end
|
10
10
|
|
11
11
|
specify "the smallest table" do
|
12
12
|
csvdata = CSV.parse("{VTABLE}")
|
13
13
|
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
14
|
-
table_list.size.
|
15
|
-
table_list.first.to_a.
|
14
|
+
table_list.size.should == 1
|
15
|
+
table_list.first.to_a.should == [["{VTABLE}"]]
|
16
16
|
end
|
17
17
|
|
18
18
|
specify "the single table" do
|
19
19
|
csvdata = CSV.parse("{HTABLE}\na,b\n1,2")
|
20
20
|
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
21
|
-
table_list.size.
|
22
|
-
table_list.first.to_a.
|
21
|
+
table_list.size.should == 1
|
22
|
+
table_list.first.to_a.should == [["{HTABLE}"],["a","b"],["1","2"]]
|
23
23
|
end
|
24
24
|
|
25
25
|
specify "the multiple table" do
|
26
26
|
csvdata = CSV.parse("{VTABLE}\n{L}\na,b\n{HTABLE}\n{L}\n1,2")
|
27
27
|
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
28
|
-
table_list.size.
|
29
|
-
table_list[0].to_a.
|
30
|
-
table_list[1].to_a.
|
28
|
+
table_list.size.should == 2
|
29
|
+
table_list[0].to_a.should == [["{VTABLE}"],["{L}"],["a","b"]]
|
30
|
+
table_list[1].to_a.should == [["{HTABLE}"],["{L}"],["1","2"]]
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -35,13 +35,13 @@ context "parse tables:" do
|
|
35
35
|
specify "empty" do
|
36
36
|
csvdata = CSV.parse("")
|
37
37
|
tables = Hyogen.parse_tables(csvdata)
|
38
|
-
tables.
|
38
|
+
tables.should == []
|
39
39
|
end
|
40
40
|
|
41
41
|
specify "single table" do
|
42
42
|
csvdata = CSV.parse("{VTABLE}\n")
|
43
43
|
tables = Hyogen.parse_tables(csvdata)
|
44
|
-
tables.size.
|
44
|
+
tables.size.should == 1
|
45
45
|
tables.first.title.should == ""
|
46
46
|
end
|
47
47
|
|
@@ -49,13 +49,13 @@ context "parse tables:" do
|
|
49
49
|
csvdata = CSV.parse("test table{VTABLE}\n")
|
50
50
|
tables = Hyogen.parse_tables(csvdata)
|
51
51
|
tables.size.should == 1
|
52
|
-
tables.first.title.
|
52
|
+
tables.first.title.should == "test table"
|
53
53
|
end
|
54
54
|
|
55
55
|
specify "multiple tables" do
|
56
56
|
csvdata = CSV.parse("{VTABLE}\n{L}\n{HTABLE}\n{L}")
|
57
57
|
tables = Hyogen.parse_tables(csvdata)
|
58
|
-
tables.size.
|
58
|
+
tables.size.should == 2
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -64,7 +64,7 @@ context "parse label:" do
|
|
64
64
|
specify "hlabel" do
|
65
65
|
csvdata = CSV.parse("test data{VTABLE}\n{L}l1,l2\n,A\n,B")
|
66
66
|
tables = Hyogen.parse_tables(csvdata)
|
67
|
-
tables.size.
|
67
|
+
tables.size.should == 1
|
68
68
|
table = tables.first
|
69
69
|
table.labels.size.should == 2
|
70
70
|
table.labels[0].names.should == ["l1"]
|
@@ -74,7 +74,7 @@ context "parse label:" do
|
|
74
74
|
specify "vlabel" do
|
75
75
|
csvdata = CSV.parse("test data{HTABLE}\n{L}l1,A\nl2,B")
|
76
76
|
tables = Hyogen.parse_tables(csvdata)
|
77
|
-
tables.size.
|
77
|
+
tables.size.should == 1
|
78
78
|
table = tables.first
|
79
79
|
table.labels.size.should == 2
|
80
80
|
table.labels[0].names.should == ["l1"]
|
@@ -89,14 +89,14 @@ context "Table has single label:" do
|
|
89
89
|
specify "vtable label" do
|
90
90
|
csvdata = CSV.parse("test data{VTABLE}\n{L}l\nA\nB")
|
91
91
|
tables = Hyogen.parse_tables(csvdata)
|
92
|
-
tables.size.
|
92
|
+
tables.size.should == 1
|
93
93
|
tables.first.records.should == expect
|
94
94
|
end
|
95
95
|
|
96
96
|
specify "htable label" do
|
97
97
|
csvdata = CSV.parse("test data{HTABLE},,\nl{L},A,B")
|
98
98
|
tables = Hyogen.parse_tables(csvdata)
|
99
|
-
tables.size.
|
99
|
+
tables.size.should == 1
|
100
100
|
table = tables.first
|
101
101
|
table.records.should == expect
|
102
102
|
end
|
@@ -107,16 +107,16 @@ context "redudancy:" do
|
|
107
107
|
specify "table" do
|
108
108
|
csvdata = CSV.parse("{VTABLE}\n\n{L}a,b\n\n{HTABLE}\n{L}1,2\n\nhoge")
|
109
109
|
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
110
|
-
table_list.size.
|
111
|
-
table_list[0].to_a.
|
112
|
-
table_list[1].to_a.
|
110
|
+
table_list.size.should == 2
|
111
|
+
table_list[0].to_a.should == [["{VTABLE}"],[nil],["{L}a","b"]]
|
112
|
+
table_list[1].to_a.should == [["{HTABLE}"],["{L}1","2"]]
|
113
113
|
end
|
114
114
|
|
115
115
|
specify "data" do
|
116
116
|
expect = [{"l"=>"A"}, {"l"=>"B"}]
|
117
117
|
csvdata = CSV.parse("test data {VTABLE} \n\n {L} l \n A \nB \n")
|
118
118
|
tables = Hyogen.parse_tables(csvdata)
|
119
|
-
tables.size.
|
119
|
+
tables.size.should == 1
|
120
120
|
tables.first.title.should == "test data"
|
121
121
|
tables.first.records.should == expect
|
122
122
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: hyogen
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-05-
|
6
|
+
version: 0.0.2
|
7
|
+
date: 2007-05-14 00:00:00 +09:00
|
8
8
|
summary: This package allows you to mapping CSV or Excel to Ruby objects and generating some data.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -32,13 +32,16 @@ files:
|
|
32
32
|
- History.txt
|
33
33
|
- Manifest.txt
|
34
34
|
- README.txt
|
35
|
+
- README
|
35
36
|
- Rakefile
|
37
|
+
- bin/hyogen
|
36
38
|
- lib/hyogen.rb
|
39
|
+
- lib/hyogen/reader.rb
|
40
|
+
- lib/hyogen/table_elements.rb
|
41
|
+
- lib/hyogen/template.rb
|
37
42
|
- lib/hyogen/version.rb
|
38
43
|
- scripts/txt2html
|
39
44
|
- setup.rb
|
40
|
-
- test/test_helper.rb
|
41
|
-
- test/test_hyogen.rb
|
42
45
|
- website/index.html
|
43
46
|
- website/index.txt
|
44
47
|
- website/javascripts/rounded_corners_lite.inc.js
|
@@ -50,13 +53,12 @@ test_files:
|
|
50
53
|
- spec/sample1.txt.template
|
51
54
|
- spec/sample1.xls
|
52
55
|
- spec/spec_hyogen.rb
|
53
|
-
- spec/spec_hyogen.rb.1~
|
54
56
|
rdoc_options: []
|
55
57
|
|
56
58
|
extra_rdoc_files: []
|
57
59
|
|
58
|
-
executables:
|
59
|
-
|
60
|
+
executables:
|
61
|
+
- hyogen
|
60
62
|
extensions: []
|
61
63
|
|
62
64
|
requirements: []
|
data/spec/spec_hyogen.rb.1~
DELETED
@@ -1,294 +0,0 @@
|
|
1
|
-
require 'lib/hyogen'
|
2
|
-
require 'spec'
|
3
|
-
|
4
|
-
|
5
|
-
context "deviding csvlines into tables:" do
|
6
|
-
specify "empty" do
|
7
|
-
csvdata = CSV.parse("")
|
8
|
-
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
9
|
-
table_list.should_eql []
|
10
|
-
end
|
11
|
-
|
12
|
-
specify "the smallest table" do
|
13
|
-
csvdata = CSV.parse("{VTABLE}")
|
14
|
-
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
15
|
-
table_list.size.should_eql 1
|
16
|
-
table_list.first.to_a.should_eql [["{VTABLE}"]]
|
17
|
-
end
|
18
|
-
|
19
|
-
specify "the single table" do
|
20
|
-
csvdata = CSV.parse("{HTABLE}\na,b\n1,2")
|
21
|
-
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
22
|
-
table_list.size.should_eql 1
|
23
|
-
table_list.first.to_a.should_eql [["{HTABLE}"],["a","b"],["1","2"]]
|
24
|
-
end
|
25
|
-
|
26
|
-
specify "the multiple table" do
|
27
|
-
csvdata = CSV.parse("{VTABLE}\n{L}\na,b\n{HTABLE}\n{L}\n1,2")
|
28
|
-
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
29
|
-
table_list.size.should_eql 2
|
30
|
-
table_list[0].to_a.should_eql [["{VTABLE}"],["{L}"],["a","b"]]
|
31
|
-
table_list[1].to_a.should_eql [["{HTABLE}"],["{L}"],["1","2"]]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "parse tables:" do
|
36
|
-
specify "empty" do
|
37
|
-
csvdata = CSV.parse("")
|
38
|
-
tables = Hyogen.parse_tables(csvdata)
|
39
|
-
tables.should_eql []
|
40
|
-
end
|
41
|
-
|
42
|
-
specify "single table" do
|
43
|
-
csvdata = CSV.parse("{VTABLE}\n")
|
44
|
-
tables = Hyogen.parse_tables(csvdata)
|
45
|
-
tables.size.should_equal 1
|
46
|
-
tables.first.title.should == ""
|
47
|
-
end
|
48
|
-
|
49
|
-
specify "labeled table" do
|
50
|
-
csvdata = CSV.parse("test table{VTABLE}\n")
|
51
|
-
tables = Hyogen.parse_tables(csvdata)
|
52
|
-
tables.size.should == 1
|
53
|
-
tables.first.title.should_eql "test table"
|
54
|
-
end
|
55
|
-
|
56
|
-
specify "multiple tables" do
|
57
|
-
csvdata = CSV.parse("{VTABLE}\n{L}\n{HTABLE}\n{L}")
|
58
|
-
tables = Hyogen.parse_tables(csvdata)
|
59
|
-
tables.size.should_equal 2
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
context "parse label:" do
|
64
|
-
expect = [{"l1"=>"A"}, {"l2"=>"B"}]
|
65
|
-
specify "hlabel" do
|
66
|
-
csvdata = CSV.parse("test data{VTABLE}\n{L}l1,l2\n,A\n,B")
|
67
|
-
tables = Hyogen.parse_tables(csvdata)
|
68
|
-
tables.size.should_equal 1
|
69
|
-
table = tables.first
|
70
|
-
table.labels.size.should == 2
|
71
|
-
table.labels[0].names.should == ["l1"]
|
72
|
-
table.labels[1].names.should == ["l2"]
|
73
|
-
end
|
74
|
-
|
75
|
-
specify "vlabel" do
|
76
|
-
csvdata = CSV.parse("test data{HTABLE}\n{L}l1,A\nl2,B")
|
77
|
-
tables = Hyogen.parse_tables(csvdata)
|
78
|
-
tables.size.should_equal 1
|
79
|
-
table = tables.first
|
80
|
-
table.labels.size.should == 2
|
81
|
-
table.labels[0].names.should == ["l1"]
|
82
|
-
table.labels[1].names.should == ["l2"]
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
|
-
#�P����(���x����=1)�\
|
88
|
-
context "Table has single label:" do
|
89
|
-
expect = [{"l"=>"A"}, {"l"=>"B"}]
|
90
|
-
specify "vtable label" do
|
91
|
-
csvdata = CSV.parse("test data{VTABLE}\n{L}l\nA\nB")
|
92
|
-
tables = Hyogen.parse_tables(csvdata)
|
93
|
-
tables.size.should_equal 1
|
94
|
-
tables.first.records.should == expect
|
95
|
-
end
|
96
|
-
|
97
|
-
specify "htable label" do
|
98
|
-
csvdata = CSV.parse("test data{HTABLE},,\nl{L},A,B")
|
99
|
-
tables = Hyogen.parse_tables(csvdata)
|
100
|
-
tables.size.should_equal 1
|
101
|
-
table = tables.first
|
102
|
-
table.records.should == expect
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
#�璷�ȃf�[�^���܂ޕ\
|
107
|
-
context "redudancy:" do
|
108
|
-
specify "table" do
|
109
|
-
csvdata = CSV.parse("{VTABLE}\n\n{L}a,b\n\n{HTABLE}\n{L}1,2\n\nhoge")
|
110
|
-
table_list = Hyogen::Reader.devide_into_table(Hyogen::Reader::Matrix.new(csvdata))
|
111
|
-
table_list.size.should_eql 2
|
112
|
-
table_list[0].to_a.should_eql [["{VTABLE}"],[nil],["{L}a","b"]]
|
113
|
-
table_list[1].to_a.should_eql [["{HTABLE}"],["{L}1","2"]]
|
114
|
-
end
|
115
|
-
|
116
|
-
specify "data" do
|
117
|
-
expect = [{"l"=>"A"}, {"l"=>"B"}]
|
118
|
-
csvdata = CSV.parse("test data {VTABLE} \n\n {L} l \n A \nB \n")
|
119
|
-
tables = Hyogen.parse_tables(csvdata)
|
120
|
-
tables.size.should_equal 1
|
121
|
-
tables.first.title.should == "test data"
|
122
|
-
tables.first.records.should == expect
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
#�����̃��R�[�h�ƕ����̃��x�������\
|
127
|
-
context "Table has multiple records and multiple labels:" do
|
128
|
-
expect = [{"name"=>"A", "age"=>"10"}, {"name"=>"B", "age"=>"20"}]
|
129
|
-
specify "vertical" do
|
130
|
-
csvdata = CSV.parse("{VTABLE}\n{L}name,age\nA,10\nB,20")
|
131
|
-
table = Hyogen.parse_tables(csvdata).first
|
132
|
-
table.records.should == expect
|
133
|
-
end
|
134
|
-
|
135
|
-
specify "horizontal" do
|
136
|
-
csvdata = CSV.parse("{HTABLE},,\n{L}name,A,B\nage,10,20")
|
137
|
-
table = Hyogen.parse_tables(csvdata).first
|
138
|
-
table.records.should == expect
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
#�K�w�̂���\
|
143
|
-
context "Table is structured" do
|
144
|
-
expect = [{"category"=> {"type" => "C"}}]
|
145
|
-
specify "vtable" do
|
146
|
-
csvdata = CSV.parse("{VTABLE}\n{L}category\n{L}type\nC")
|
147
|
-
table = Hyogen.parse_tables(csvdata).first
|
148
|
-
table.records.should == expect
|
149
|
-
end
|
150
|
-
specify "htable" do
|
151
|
-
csvdata = CSV.parse("{HTABLE},,o\n{L}category,{L}type,C")
|
152
|
-
table = Hyogen.parse_tables(csvdata).first
|
153
|
-
table.records.should == expect
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
#�⑫�^�O
|
158
|
-
context "Note Tag" do
|
159
|
-
expect_records = [
|
160
|
-
{""=>"id1", "name"=> "alice", "age" => "10"},
|
161
|
-
{""=>"id2", "name"=> "bob", "age" => "20"},
|
162
|
-
]
|
163
|
-
specify "" do
|
164
|
-
csvdata = CSV.parse("{HTABLE}\n{L},id1,id2,{N}�⑫\nname,alice,bob,���O\nage,10,20,��")
|
165
|
-
table = Hyogen.parse_tables(csvdata).first
|
166
|
-
table.records.should == expect_records
|
167
|
-
|
168
|
-
table.labels[0].note.should == {"�⑫" => "�⑫"}
|
169
|
-
table.labels[1].note.should == {"�⑫" => "���O"}
|
170
|
-
table.labels[2].note.should == {"�⑫" => "��"}
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
|
175
|
-
context "Matrix of Excel Worksheet:" do
|
176
|
-
specify "" do
|
177
|
-
file = "./spec/sample1.xls"
|
178
|
-
workbook = Spreadsheet::ParseExcel.parse(file)
|
179
|
-
ws = workbook.worksheet(0)
|
180
|
-
matrix = Hyogen::Reader::worksheet_to_matrix(ws)
|
181
|
-
matrix.row_size.should == 4
|
182
|
-
matrix.column_size(0).should == 1
|
183
|
-
matrix.column_size(1).should == 4
|
184
|
-
|
185
|
-
matrix.value(0,0).should == "{HTABLE}"
|
186
|
-
matrix.row(1).should == ["{L}", "id1", "id2", "{N}�⑫"]
|
187
|
-
matrix.to_a.should == [
|
188
|
-
["{HTABLE}"],
|
189
|
-
["{L}", "id1", "id2", "{N}�⑫"],
|
190
|
-
["name", "Alice", "Bob", "���O"],
|
191
|
-
["age", "10.0", "20.0", "��"]
|
192
|
-
]
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
#�e��t�@�C���t�H�[�}�b�g
|
197
|
-
context "File formats" do
|
198
|
-
def check table
|
199
|
-
expect_records = [
|
200
|
-
{""=>"id1", "name"=> "Alice", "age" => "10.0"},
|
201
|
-
{""=>"id2", "name"=> "Bob", "age" => "20.0"},
|
202
|
-
]
|
203
|
-
table.records.should == expect_records
|
204
|
-
table.labels[0].note.should == {"�⑫" => "�⑫"}
|
205
|
-
table.labels[1].note.should == {"�⑫" => "���O"}
|
206
|
-
table.labels[2].note.should == {"�⑫" => "��"}
|
207
|
-
end
|
208
|
-
specify "csv string" do
|
209
|
-
input = "{HTABLE}\n{L},id1,id2,{N}�⑫\nname,Alice,Bob,���O\nage,10.0,20.0,��"
|
210
|
-
check Hyogen.parse_tables(input).first
|
211
|
-
end
|
212
|
-
specify "csv array" do
|
213
|
-
input = CSV.parse("{HTABLE}\n{L},id1,id2,{N}�⑫\nname,Alice,Bob,���O\nage,10.0,20.0,��")
|
214
|
-
check Hyogen.parse_tables(input).first
|
215
|
-
end
|
216
|
-
specify "csv file" do
|
217
|
-
input = "./spec/sample1.csv"
|
218
|
-
check Hyogen.parse_tables(input).first
|
219
|
-
end
|
220
|
-
specify "xls file" do
|
221
|
-
input = "./spec/sample1.xls"
|
222
|
-
check Hyogen.parse_tables(input).first
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
|
227
|
-
#�ȗ�
|
228
|
-
context "label syoryaku" do
|
229
|
-
specify "vtable" do
|
230
|
-
csvdata = CSV.parse("{VTABLE},\n{L}a,\n{L}t1,t2\n1,2")
|
231
|
-
expect = [{"a"=> {"t1" => "1", "t2" => "2"}}]
|
232
|
-
table = Hyogen.parse_tables(csvdata).first
|
233
|
-
table.records.should == expect
|
234
|
-
end
|
235
|
-
|
236
|
-
specify "overwrite" do
|
237
|
-
csvdata = CSV.parse("{VTABLE},\n{L}a,\n{L}t,\n1,2")
|
238
|
-
expect = [{"a"=> {"t" => "2"}}]
|
239
|
-
table = Hyogen.parse_tables(csvdata).first
|
240
|
-
table.records.should == expect
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
#�u��
|
245
|
-
context "alias" do
|
246
|
-
specify "label" do
|
247
|
-
csvdata = CSV.parse("{VTABLE},\n{L}a,\n{L}t1,t2<abc>\n1,2")
|
248
|
-
expect = [{"a"=> {"t1" => "1", "abc" => "2"}}]
|
249
|
-
table = Hyogen.parse_tables(csvdata).first
|
250
|
-
table.records.should == expect
|
251
|
-
end
|
252
|
-
|
253
|
-
specify "value" do
|
254
|
-
csvdata = CSV.parse("{VTABLE},\n{L}a,\n{L}t1,t2\n1,2 <2.00>")
|
255
|
-
expect = [{"a"=> {"t1" => "1", "t2" => "2.00"}}]
|
256
|
-
table = Hyogen.parse_tables(csvdata).first
|
257
|
-
table.records.should == expect
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
#����
|
262
|
-
context "generate:" do
|
263
|
-
def check table
|
264
|
-
expect_records = [
|
265
|
-
{""=>"id1", "name"=> "alice", "age" => "10.0"},
|
266
|
-
{""=>"id2", "name"=> "bob", "age" => "20.0"},
|
267
|
-
]
|
268
|
-
table.records.should == expect_records
|
269
|
-
table.labels[0].note.should == {"�⑫" => "�⑫"}
|
270
|
-
table.labels[1].note.should == {"�⑫" => "���O"}
|
271
|
-
table.labels[2].note.should == {"�⑫" => "��"}
|
272
|
-
end
|
273
|
-
specify "from script" do
|
274
|
-
input = "{HTABLE}\n{L},id1,id2,{N}�⑫\nname,Alice,Bob,���O\nage,10.0,20.0,��"
|
275
|
-
tables = Hyogen.parse_tables(input)
|
276
|
-
begin
|
277
|
-
File.delete('./spec/sample1.txt')
|
278
|
-
rescue Errno::ENOENT
|
279
|
-
end
|
280
|
-
Hyogen::Template.generate(tables, './spec/sample1.txt.template', './spec')
|
281
|
-
result = File.open('./spec/sample1.txt') {|f| f.read}
|
282
|
-
result.should == "My name is Alice. I'm 10 years old.\nMy name is Bob. I'm 20 years old.\n"
|
283
|
-
end
|
284
|
-
specify "from shell" do
|
285
|
-
begin
|
286
|
-
File.delete('./spec/sample1.txt')
|
287
|
-
rescue Errno::ENOENT
|
288
|
-
end
|
289
|
-
result = system 'ruby', 'hyogen', '-s', './spec/sample1.xls', './spec/sample1.txt.template', '-o', './spec'
|
290
|
-
result.should == true
|
291
|
-
result = File.open('./spec/sample1.txt') {|f| f.read}
|
292
|
-
result.should == "My name is Alice. I'm 10 years old.\nMy name is Bob. I'm 20 years old.\n"
|
293
|
-
end
|
294
|
-
end
|
data/test/test_helper.rb
DELETED