htot_conv 0.3.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +135 -135
- data/.travis.yml +12 -12
- data/Gemfile +4 -4
- data/LICENSE.txt +21 -21
- data/README.md +46 -138
- data/Rakefile +10 -10
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/docs/image/output_xlsx_type0.png +0 -0
- data/docs/image/output_xlsx_type1.png +0 -0
- data/docs/image/output_xlsx_type1_outline_rows_yes.png +0 -0
- data/docs/image/output_xlsx_type2.png +0 -0
- data/docs/image/output_xlsx_type2_integrate_cells_colspan.png +0 -0
- data/docs/image/output_xlsx_type2_outline_rows_yes.png +0 -0
- data/docs/image/output_xlsx_type3.png +0 -0
- data/docs/image/output_xlsx_type3_integrate_cells_both.png +0 -0
- data/docs/image/output_xlsx_type4.png +0 -0
- data/docs/image/output_xlsx_type4_integrate_cells_both.png +0 -0
- data/docs/image/output_xlsx_type5.png +0 -0
- data/docs/image/output_xlsx_type5_integrate_cells_colspan.png +0 -0
- data/docs/index.md +88 -0
- data/exe/htot_conv +8 -8
- data/htot_conv.gemspec +37 -37
- data/lib/htot_conv.rb +20 -20
- data/lib/htot_conv/cli.rb +174 -174
- data/lib/htot_conv/generator.rb +30 -30
- data/lib/htot_conv/generator/base.rb +34 -35
- data/lib/htot_conv/generator/xlsx_type0.rb +36 -24
- data/lib/htot_conv/generator/xlsx_type1.rb +57 -69
- data/lib/htot_conv/generator/xlsx_type2.rb +100 -104
- data/lib/htot_conv/generator/xlsx_type3.rb +99 -85
- data/lib/htot_conv/generator/xlsx_type4.rb +109 -84
- data/lib/htot_conv/generator/xlsx_type5.rb +75 -62
- data/lib/htot_conv/outline.rb +176 -176
- data/lib/htot_conv/parser.rb +27 -27
- data/lib/htot_conv/parser/base.rb +15 -15
- data/lib/htot_conv/parser/dir_tree.rb +54 -54
- data/lib/htot_conv/parser/html_list.rb +71 -71
- data/lib/htot_conv/parser/opml.rb +70 -70
- data/lib/htot_conv/parser/simple_text.rb +70 -70
- data/lib/htot_conv/util.rb +13 -13
- data/lib/htot_conv/version.rb +4 -4
- metadata +19 -6
@@ -1,85 +1,99 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
:
|
13
|
-
:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@data.key_header[0],
|
25
|
-
*(HTOTConv::Util.pad_array([@data.value_header[0]], max_level)),
|
26
|
-
*(HTOTConv::Util.pad_array(
|
27
|
-
(@data.value_header.length <= 1)? [] : @data.value_header.last(@data.value_header.length - 1),
|
28
|
-
[max_value_length - 1, 0].max)),
|
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
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
(
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'htot_conv/generator/base'
|
4
|
+
|
5
|
+
module HTOTConv
|
6
|
+
module Generator
|
7
|
+
class XlsxType3 < XlsxBase
|
8
|
+
def self.option_help
|
9
|
+
{
|
10
|
+
:integrate_cells => {
|
11
|
+
:default => nil,
|
12
|
+
:pat => [:colspan, :rowspan, :both],
|
13
|
+
:desc => "integrate key cells (specify 'colspan', 'rowspan' or 'both')",
|
14
|
+
},
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def output_to_worksheet(ws)
|
19
|
+
max_level = @data.max_level
|
20
|
+
max_value_length = @data.max_value_length
|
21
|
+
row_index = 0
|
22
|
+
|
23
|
+
[
|
24
|
+
@data.key_header[0],
|
25
|
+
*(HTOTConv::Util.pad_array([@data.value_header[0]], max_level)),
|
26
|
+
*(HTOTConv::Util.pad_array(
|
27
|
+
(@data.value_header.length <= 1)? [] : @data.value_header.last(@data.value_header.length - 1),
|
28
|
+
[max_value_length - 1, 0].max)),
|
29
|
+
].each_with_index do |v, col_index|
|
30
|
+
ws.add_cell(row_index, col_index, v)
|
31
|
+
[:top, :bottom, :left, :right].each do |edge|
|
32
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
1.upto(max_level) do |col_index|
|
36
|
+
edges = []
|
37
|
+
edges << :left unless (col_index <= 1)
|
38
|
+
edges << :right unless (col_index >= max_level)
|
39
|
+
edges.each do |edge|
|
40
|
+
ws[row_index][col_index].change_border(edge, nil)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
row_index = row_index.succ
|
44
|
+
|
45
|
+
@data.item.each_with_index do |item, item_index|
|
46
|
+
key_value_cell = Array.new(max_level + 1, nil)
|
47
|
+
key_value_cell[item.level - 1] = item.key
|
48
|
+
key_value_cell[item.level ] = item.value[0]
|
49
|
+
rest_value_cell = HTOTConv::Util.pad_array(
|
50
|
+
(item.value.length <= 1)? [] : item.value.last(item.value.length - 1),
|
51
|
+
[max_value_length - 1, 0].max)
|
52
|
+
|
53
|
+
key_value_cell.concat(rest_value_cell).each_with_index do |v, col_index|
|
54
|
+
ws.add_cell(row_index, col_index, v)
|
55
|
+
[:top, :bottom, :left, :right].each do |edge|
|
56
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
0.upto(max_level) do |col_index|
|
60
|
+
edges = []
|
61
|
+
edges << :left unless (col_index <= item.level)
|
62
|
+
edges << :right unless ((col_index < item.level) || (col_index >= max_level))
|
63
|
+
edges << :top unless ((col_index > (item.level - 2)) || (item_index == 0))
|
64
|
+
edges << :bottom unless ((col_index > (item.level - 1)) || (item_index == @data.item.length - 1))
|
65
|
+
edges.each do |edge|
|
66
|
+
ws[row_index][col_index].change_border(edge, nil)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
row_index = row_index.succ
|
70
|
+
end
|
71
|
+
|
72
|
+
if [:colspan, :both].include?(@option[:integrate_cells])
|
73
|
+
if max_level > 1
|
74
|
+
ws.merge_cells(0, 1, 0, max_level)
|
75
|
+
end
|
76
|
+
@data.item.each_with_index do |item, item_index|
|
77
|
+
if item.level < max_level
|
78
|
+
ws.merge_cells(item_index + 1, item.level, item_index + 1, max_level)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
if [:rowspan, :both].include?(@option[:integrate_cells])
|
83
|
+
@data.item.each_with_index do |item, item_index|
|
84
|
+
min_row_index = item_index + 1
|
85
|
+
max_row_index = min_row_index
|
86
|
+
((item_index + 1)..(@data.item.length - 1)).each do |i|
|
87
|
+
break if @data.item[i].level <= item.level
|
88
|
+
max_row_index = i + 1
|
89
|
+
end
|
90
|
+
|
91
|
+
unless min_row_index == max_row_index
|
92
|
+
ws.merge_cells(min_row_index, item.level - 1, max_row_index, item.level - 1)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -1,84 +1,109 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
:
|
13
|
-
:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
HTOTConv::Util.pad_array(@data.value_header, max_value_length)
|
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
|
-
end
|
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
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'htot_conv/generator/base'
|
4
|
+
|
5
|
+
module HTOTConv
|
6
|
+
module Generator
|
7
|
+
class XlsxType4 < XlsxBase
|
8
|
+
def self.option_help
|
9
|
+
{
|
10
|
+
:integrate_cells => {
|
11
|
+
:default => nil,
|
12
|
+
:pat => [:colspan, :rowspan, :both],
|
13
|
+
:desc => "integrate key cells (specify 'colspan', 'rowspan' or 'both')",
|
14
|
+
},
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def output_to_worksheet(ws)
|
19
|
+
max_level = @data.max_level
|
20
|
+
max_value_length = @data.max_value_length
|
21
|
+
row_index = 0
|
22
|
+
|
23
|
+
((1..max_level).map {|l| @data.key_header[l - 1] || nil }).concat(
|
24
|
+
HTOTConv::Util.pad_array(@data.value_header, max_value_length)
|
25
|
+
).each_with_index do |v, col_index|
|
26
|
+
ws.add_cell(row_index, col_index, v)
|
27
|
+
[:top, :bottom, :left, :right].each do |edge|
|
28
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
row_index = row_index.succ
|
32
|
+
|
33
|
+
rowspan_cells = Array.new(max_level) { [] }
|
34
|
+
@data.to_tree.descendants.each do |node|
|
35
|
+
if node.leaf?
|
36
|
+
item = node.item
|
37
|
+
|
38
|
+
key_cell = Array.new(max_level, nil)
|
39
|
+
[node].concat(node.ancestors.to_a).each do |c_node|
|
40
|
+
key_cell[c_node.item.level - 1] = c_node.item.key if c_node.item
|
41
|
+
break if c_node.prev
|
42
|
+
end
|
43
|
+
|
44
|
+
value_cell = HTOTConv::Util.pad_array(item.value, max_value_length)
|
45
|
+
|
46
|
+
key_cell.concat(value_cell).each_with_index do |v, col_index|
|
47
|
+
ws.add_cell(row_index, col_index, v)
|
48
|
+
[:top, :bottom, :left, :right].each do |edge|
|
49
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
node.ancestors.each_with_object([node]) do |c_node, descendants|
|
54
|
+
if (c_node.item && c_node.item.level)
|
55
|
+
edges = []
|
56
|
+
edges << :top if (descendants.any? { |v| v.prev })
|
57
|
+
edges << :bottom if (descendants.any? { |v| v.next })
|
58
|
+
edges.each do |edge|
|
59
|
+
ws[row_index][c_node.item.level - 1].change_border(edge, nil)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
descendants.unshift(c_node)
|
63
|
+
end
|
64
|
+
(item.level..max_level).each do |level|
|
65
|
+
edges = []
|
66
|
+
edges << :left unless (level == item.level)
|
67
|
+
edges << :right unless (level == max_level)
|
68
|
+
edges.each do |edge|
|
69
|
+
ws[row_index][level - 1].change_border(edge, nil)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
if [:colspan, :both].include?(@option[:integrate_cells])
|
74
|
+
if item.level < max_level
|
75
|
+
ws.merge_cells(row_index, item.level - 1, row_index, max_level - 1)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
node.ancestors.each_with_object([node]) do |c_node, descendants|
|
80
|
+
rowspan_cells[c_node.item.level - 1] << [row_index, c_node.item.level - 1]
|
81
|
+
unless (descendants.any? { |v| v.next })
|
82
|
+
if [:rowspan, :both].include?(@option[:integrate_cells])
|
83
|
+
if rowspan_cells[c_node.item.level - 1].length > 1
|
84
|
+
ws.merge_cells(
|
85
|
+
rowspan_cells[c_node.item.level - 1].map(&:first).min,
|
86
|
+
rowspan_cells[c_node.item.level - 1].map(&:last).min,
|
87
|
+
rowspan_cells[c_node.item.level - 1].map(&:first).max,
|
88
|
+
rowspan_cells[c_node.item.level - 1].map(&:last).max,
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
rowspan_cells[c_node.item.level - 1].clear
|
93
|
+
end
|
94
|
+
descendants.unshift(c_node)
|
95
|
+
end
|
96
|
+
|
97
|
+
(max_level..(max_level + max_value_length - 1)).each do |col_index|
|
98
|
+
[:top, :bottom, :left, :right].each do |edge|
|
99
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
row_index = row_index.succ
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,62 +1,75 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
:
|
13
|
-
:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
HTOTConv::Util.pad_array(@data.value_header, max_value_length)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
ws.
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'htot_conv/generator/base'
|
4
|
+
|
5
|
+
module HTOTConv
|
6
|
+
module Generator
|
7
|
+
class XlsxType5 < XlsxBase
|
8
|
+
def self.option_help
|
9
|
+
{
|
10
|
+
:integrate_cells => {
|
11
|
+
:default => nil,
|
12
|
+
:pat => [:colspan],
|
13
|
+
:desc => "integrate key cells (specify 'colspan')",
|
14
|
+
},
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def output_to_worksheet(ws)
|
19
|
+
max_level = @data.max_level
|
20
|
+
max_value_length = @data.max_value_length
|
21
|
+
row_index = 0
|
22
|
+
|
23
|
+
((1..max_level).map {|l| @data.key_header[l - 1] || nil }).concat(
|
24
|
+
HTOTConv::Util.pad_array(@data.value_header, max_value_length)
|
25
|
+
).each_with_index do |v, col_index|
|
26
|
+
ws.add_cell(row_index, col_index, v)
|
27
|
+
[:top, :bottom, :left, :right].each do |edge|
|
28
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
row_index = row_index.succ
|
32
|
+
|
33
|
+
@data.to_tree.descendants.each do |node|
|
34
|
+
if node.leaf?
|
35
|
+
item = node.item
|
36
|
+
|
37
|
+
key_cell = Array.new(max_level, nil)
|
38
|
+
key_cell[node.item.level - 1] = item.key
|
39
|
+
node.ancestors.each do |ancestor|
|
40
|
+
key_cell[ancestor.item.level - 1] = ancestor.item.key if ancestor.item
|
41
|
+
end
|
42
|
+
|
43
|
+
value_cell = HTOTConv::Util.pad_array(item.value, max_value_length)
|
44
|
+
|
45
|
+
key_cell.concat(value_cell).each_with_index do |v, col_index|
|
46
|
+
ws.add_cell(row_index, col_index, v)
|
47
|
+
[:top, :bottom, :left, :right].each do |edge|
|
48
|
+
ws[row_index][col_index].change_border(edge, "thin")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
(item.level..max_level).each do |level|
|
53
|
+
edges = []
|
54
|
+
edges << :left unless (level == item.level)
|
55
|
+
edges << :right unless (level == max_level)
|
56
|
+
edges.each do |edge|
|
57
|
+
ws[row_index][level - 1].change_border(edge, nil)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if [:colspan].include?(@option[:integrate_cells])
|
62
|
+
if item.level < max_level
|
63
|
+
ws.merge_cells(row_index, item.level - 1, row_index, max_level - 1)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
row_index = row_index.succ
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
ws.auto_filter ||= RubyXL::AutoFilter.new
|
71
|
+
ws.auto_filter.ref = RubyXL::Reference.new(0, row_index - 1, 0, max_level + max_value_length -1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|