hyogen 0.0.1 → 0.0.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/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