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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +135 -135
  3. data/.travis.yml +12 -12
  4. data/Gemfile +4 -4
  5. data/LICENSE.txt +21 -21
  6. data/README.md +46 -138
  7. data/Rakefile +10 -10
  8. data/bin/console +14 -14
  9. data/bin/setup +8 -8
  10. data/docs/image/output_xlsx_type0.png +0 -0
  11. data/docs/image/output_xlsx_type1.png +0 -0
  12. data/docs/image/output_xlsx_type1_outline_rows_yes.png +0 -0
  13. data/docs/image/output_xlsx_type2.png +0 -0
  14. data/docs/image/output_xlsx_type2_integrate_cells_colspan.png +0 -0
  15. data/docs/image/output_xlsx_type2_outline_rows_yes.png +0 -0
  16. data/docs/image/output_xlsx_type3.png +0 -0
  17. data/docs/image/output_xlsx_type3_integrate_cells_both.png +0 -0
  18. data/docs/image/output_xlsx_type4.png +0 -0
  19. data/docs/image/output_xlsx_type4_integrate_cells_both.png +0 -0
  20. data/docs/image/output_xlsx_type5.png +0 -0
  21. data/docs/image/output_xlsx_type5_integrate_cells_colspan.png +0 -0
  22. data/docs/index.md +88 -0
  23. data/exe/htot_conv +8 -8
  24. data/htot_conv.gemspec +37 -37
  25. data/lib/htot_conv.rb +20 -20
  26. data/lib/htot_conv/cli.rb +174 -174
  27. data/lib/htot_conv/generator.rb +30 -30
  28. data/lib/htot_conv/generator/base.rb +34 -35
  29. data/lib/htot_conv/generator/xlsx_type0.rb +36 -24
  30. data/lib/htot_conv/generator/xlsx_type1.rb +57 -69
  31. data/lib/htot_conv/generator/xlsx_type2.rb +100 -104
  32. data/lib/htot_conv/generator/xlsx_type3.rb +99 -85
  33. data/lib/htot_conv/generator/xlsx_type4.rb +109 -84
  34. data/lib/htot_conv/generator/xlsx_type5.rb +75 -62
  35. data/lib/htot_conv/outline.rb +176 -176
  36. data/lib/htot_conv/parser.rb +27 -27
  37. data/lib/htot_conv/parser/base.rb +15 -15
  38. data/lib/htot_conv/parser/dir_tree.rb +54 -54
  39. data/lib/htot_conv/parser/html_list.rb +71 -71
  40. data/lib/htot_conv/parser/opml.rb +70 -70
  41. data/lib/htot_conv/parser/simple_text.rb +70 -70
  42. data/lib/htot_conv/util.rb +13 -13
  43. data/lib/htot_conv/version.rb +4 -4
  44. metadata +19 -6
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList['test/**/*_test.rb']
8
- end
9
-
10
- task :default => :test
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console CHANGED
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "htot_conv"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "htot_conv"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/docs/index.md ADDED
@@ -0,0 +1,88 @@
1
+ # Types of input
2
+
3
+ ## `simple_text`
4
+
5
+ * A text file consisting of multiple lines where:
6
+ * `<line> ::= { <indent> } <key> { <delimiter> <value> }`
7
+ * `<key>` : a text that does not start with `<indent>` and does not contain `<delimiter>` (if `<delimiter>` specified).
8
+ * `<value>` : a text that does not contain `<delimiter>`.
9
+ * `<indent>` : specified by `--from-indent` option
10
+ * `<delimiter>` : specified by `--from-delimiter` option
11
+
12
+ ## `dir_tree`
13
+
14
+ * Directory tree with the glob pattern specified by `--from-glob-pattern` (default: `**/*`)
15
+
16
+ ## `html_list`
17
+
18
+ * HTML `<ul><li>` and/or `<ol><li>` [nesting list](https://www.w3.org/wiki/HTML_lists#Nesting_lists).
19
+ * All text outside of `<li>` elements is ignored.
20
+
21
+ ## `opml`
22
+
23
+ * [OPML](http://dev.opml.org/)
24
+ * Treat the `text` attribute as a key text, the other attributes as values.
25
+
26
+ # Types of output
27
+
28
+ The sample input used in this section are as follows:
29
+
30
+ 1,1(1),1(2)
31
+ 1.1,1.1(1),1.1(2)
32
+ 1.2,1.2(1),1.2(2)
33
+ 1.2.1,1.2.1(1),1.2.1(2)
34
+
35
+ * key header: H1, H2, H3
36
+ * value header: H(1), H(2)
37
+
38
+ ## `xlsx_type0`
39
+
40
+ ![](image/output_xlsx_type0.png)
41
+
42
+ ## `xlsx_type1`
43
+
44
+ ![](image/output_xlsx_type1.png)
45
+
46
+ `--outline-rows=yes` : group rows
47
+
48
+ ![](image/output_xlsx_type1_outline_rows_yes.png)
49
+
50
+ Not implemented (TODO):
51
+
52
+ * Fill with different background color for each level.
53
+
54
+ ## `xlsx_type2`
55
+
56
+ ![](image/output_xlsx_type2.png)
57
+
58
+ `--integrate-cells={colspan,rowspan}` : group columns/rows.
59
+
60
+ ![](image/output_xlsx_type2_integrate_cells_colspan.png)
61
+
62
+ `--outline-rows=yes` : group rows.
63
+
64
+ ![](image/output_xlsx_type2_outline_rows_yes.png)
65
+
66
+ ## `xlsx_type3`
67
+
68
+ ![](image/output_xlsx_type3.png)
69
+
70
+ `--integrate-cells={colspan,rowspan,both}` : group columns/rows.
71
+
72
+ ![](image/output_xlsx_type3_integrate_cells_both.png)
73
+
74
+ ## `xlsx_type4`
75
+
76
+ ![](image/output_xlsx_type4.png)
77
+
78
+ `--integrate-cells={colspan,rowspan,both}` : group columns/rows.
79
+
80
+ ![](image/output_xlsx_type4_integrate_cells_both.png)
81
+
82
+ ## `xlsx_type5`
83
+
84
+ ![](image/output_xlsx_type5.png)
85
+
86
+ `--integrate-cells=colspan` : group columns/rows.
87
+
88
+ ![](image/output_xlsx_type5_integrate_cells_colspan.png)
data/exe/htot_conv CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
- #
4
- require 'rubygems'
5
- require 'htot_conv'
6
- require 'htot_conv/cli'
7
-
8
- HTOTConv::CLI.main(ARGV)
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ require 'rubygems'
5
+ require 'htot_conv'
6
+ require 'htot_conv/cli'
7
+
8
+ HTOTConv::CLI.main(ARGV)
data/htot_conv.gemspec CHANGED
@@ -1,37 +1,37 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'htot_conv/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "htot_conv"
8
- spec.version = HTOTConv::VERSION
9
- spec.authors = ["@cat_in_136"]
10
- spec.email = ["cat.in.136+github@gmail.com"]
11
-
12
- spec.summary = %q{Hierarchical-Tree Outline Text Converter}
13
- spec.description = %q{Convert from a simple hierarchical-tree outline text into ugly xlsx file}
14
- spec.homepage = "https://github.com/cat-in-136/htot_conv"
15
- spec.license = "MIT"
16
-
17
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
- # to allow pushing to a single host or delete this section to allow pushing to any host.
19
- if spec.respond_to?(:metadata)
20
- #spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
- else
22
- raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
- end
24
-
25
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
- spec.bindir = "exe"
27
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
- spec.require_paths = ["lib"]
29
-
30
- spec.add_dependency "axlsx", "~> 2.0.1"
31
- spec.add_dependency "rinne", "~> 0.0.3"
32
-
33
- spec.add_development_dependency "bundler", "~> 1.12"
34
- spec.add_development_dependency "rake", "~> 10.0"
35
- spec.add_development_dependency "minitest", "~> 5.0"
36
- spec.add_development_dependency "fakefs", "~> 0.11.3"
37
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'htot_conv/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "htot_conv"
8
+ spec.version = HTOTConv::VERSION
9
+ spec.authors = ["@cat_in_136"]
10
+ spec.email = ["cat.in.136+github@gmail.com"]
11
+
12
+ spec.summary = %q{Hierarchical-Tree Outline Text Converter}
13
+ spec.description = %q{Convert from a simple hierarchical-tree outline text into ugly xlsx file}
14
+ spec.homepage = "https://github.com/cat-in-136/htot_conv"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ #spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "rubyXL", "~> 3.3.26"
31
+ spec.add_dependency "rinne", "~> 0.0.3"
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.12"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "minitest", "~> 5.0"
36
+ spec.add_development_dependency "fakefs", "~> 0.11.3"
37
+ end
data/lib/htot_conv.rb CHANGED
@@ -1,20 +1,20 @@
1
- # frozen_string_literal: true
2
- require 'htot_conv/version'
3
-
4
- require 'htot_conv/util'
5
- require 'htot_conv/outline'
6
- require 'htot_conv/generator'
7
- require 'htot_conv/parser'
8
- # require 'htot_conv/cli'
9
-
10
- module HTOTConv
11
-
12
- def convert(input, input_type, output, output_type, input_option={}, output_option={})
13
- parser = HTOTConv::Parser.create(input_type, input_option)
14
- outline = parser.parse(input)
15
- generator = HTOTConv::Generator.create(output_type, outline, output_option)
16
- generator.output(output)
17
- end
18
- module_function :convert
19
-
20
- end
1
+ # frozen_string_literal: true
2
+ require 'htot_conv/version'
3
+
4
+ require 'htot_conv/util'
5
+ require 'htot_conv/outline'
6
+ require 'htot_conv/generator'
7
+ require 'htot_conv/parser'
8
+ # require 'htot_conv/cli'
9
+
10
+ module HTOTConv
11
+
12
+ def convert(input, input_type, output, output_type, input_option={}, output_option={})
13
+ parser = HTOTConv::Parser.create(input_type, input_option)
14
+ outline = parser.parse(input)
15
+ generator = HTOTConv::Generator.create(output_type, outline, output_option)
16
+ generator.output(output)
17
+ end
18
+ module_function :convert
19
+
20
+ end
data/lib/htot_conv/cli.rb CHANGED
@@ -1,174 +1,174 @@
1
- # frozen_string_literal: true
2
- require 'optparse'
3
-
4
- require 'rinne'
5
-
6
- module HTOTConv
7
- module CLI
8
- class ScriptOptions
9
- def initialize
10
- @options = {
11
- :from_type => :simple_text,
12
- :to_type => :xlsx_type2,
13
- }
14
- @from_options = {}
15
- @to_options = {}
16
- end
17
- attr_reader :options, :from_options, :to_options
18
-
19
- def freeze
20
- @options.freeze
21
- @from_options.freeze
22
- @to_options.freeze
23
- super
24
- end
25
-
26
- def define_options(opts, io_filter=false)
27
- opts.banner = %q{Hierarchical-Tree Outline Text Converter}
28
- opts.define_head %q{Usage: htot_conv [options] [input] [output]}
29
- opts.separator %q{}
30
- opts.separator %q{Options:}
31
-
32
- from_types = HTOTConv::Parser.types.map { |v| [v, v.to_s.tr("_", "-")] }.flatten
33
- to_types = HTOTConv::Generator.types.map { |v| [v, v.to_s.tr("_", "-")] }.flatten
34
-
35
- opts.on("-f", "--from-type=TYPE", from_types, "type of input (default: #{options[:from_type]})") do |v|
36
- @options[:from_type] = v.to_s.tr("-", "_")
37
- end
38
- opts.on("-t", "--to-type=TYPE", to_types, "type of output (default: #{options[:to_type]})") do |v|
39
- @options[:to_type] = v.to_s.tr("-", "_")
40
- end
41
- opts.on("-l", "--list-type", "list input/output type") do
42
- $stdout << "type of input:\n"
43
- $stdout << HTOTConv::Parser.types.join(" ") << "\n"
44
- $stdout << "\n"
45
- $stdout << "type of output:\n"
46
- $stdout << HTOTConv::Generator.types.join(" ") << "\n"
47
- $stdout << "\n"
48
- exit
49
- end
50
-
51
- opts.separator ""
52
- opts.on("-h", "-?", "--help", "Show this message") do
53
- puts opts
54
- exit
55
- end
56
- opts.on("--version", "Show version") do
57
- $stdout << "htot_conv #{HTOTConv::VERSION}\n"
58
- exit
59
- end
60
-
61
- opts.separator ""
62
- opts.separator "I/O Options:"
63
- if io_filter
64
- define_sub_options_of(opts, HTOTConv::Parser, @options[:from_type], "from") do |key, v|
65
- @from_options[key] = v
66
- end
67
- define_sub_options_of(opts, HTOTConv::Generator, @options[:to_type], "to") do |key, v|
68
- @to_options[key] = v
69
- end
70
- else
71
- define_sub_options(opts, HTOTConv::Parser, "from") do |key, v|
72
- @from_options[key] = v
73
- end
74
- define_sub_options(opts, HTOTConv::Generator, "to") do |key, v|
75
- @to_options[key] = v
76
- end
77
- end
78
- end
79
-
80
- private
81
- def add_sub_options_of_a_type_to!(cli_options, opts, klass, type, prefix)
82
- type_klass = klass.const_get(Rinne.camelize(type.to_s))
83
- type_klass.option_help.each do |key,v|
84
- long_option = "--#{prefix}-#{key.to_s.tr('_','-')}"
85
-
86
- if cli_options.include?(long_option)
87
- cli_options[long_option][:desc] << "For #{type}, #{v[:desc]}"
88
- unless cli_options[long_option][:pattern] == v[:pat]
89
- if (cli_options[long_option][:pattern].kind_of?(Array) && v[:pat].kind_of?(Array))
90
- cli_options[long_option][:pattern] = cli_options[long_option][:pattern].concat(v[:pat]).uniq
91
- else
92
- raise "pattern registration mismatch around #{long_option}"
93
- end
94
- end
95
- else
96
- cli_options[long_option] = {
97
- :key => key,
98
- :pattern => v[:pat],
99
- :desc => ["For #{type}, #{v[:desc]}"],
100
- }
101
- end
102
- end
103
- end
104
-
105
- private
106
- def define_sub_options_of(opts, klass, type, prefix) # :yields: key, v
107
- cli_options = {}
108
-
109
- add_sub_options_of_a_type_to!(cli_options, opts, klass, type, prefix)
110
-
111
- cli_options.each do |long_option, value|
112
- opts.on("#{long_option}=VAL", value[:pattern], *value[:desc]) do |v|
113
- yield value[:key], v
114
- end
115
- end
116
- end
117
-
118
- private
119
- def define_sub_options(opts, klass, prefix) # :yields: key, v
120
- cli_options = {}
121
-
122
- klass.types.each do |type|
123
- add_sub_options_of_a_type_to!(cli_options, opts, klass, type, prefix)
124
- end
125
-
126
- cli_options.each do |long_option, value|
127
- opts.on("#{long_option}=VAL", value[:pattern], *value[:desc]) do |v|
128
- yield value[:key], v
129
- end
130
- end
131
- end
132
- end
133
-
134
- def optparse!(args)
135
- script_opts = ScriptOptions.new
136
- OptionParser.new do |opts|
137
- script_opts.define_options(opts)
138
-
139
- begin
140
- opts.parse!(args.dup)
141
- rescue OptionParser::ParseError => ex
142
- $stderr << ex.message << "\n"
143
- exit 1
144
- end
145
- end
146
-
147
- OptionParser.new do |opts|
148
- script_opts.define_options(opts, true)
149
-
150
- begin
151
- opts.parse!(args)
152
- rescue OptionParser::ParseError => ex
153
- $stderr << ex.message << "\n"
154
- exit 1
155
- end
156
- end
157
- script_opts.freeze
158
- end
159
- module_function :optparse!
160
-
161
- def main(args=ARGV)
162
- script_opts = HTOTConv::CLI.optparse!(args)
163
- options = script_opts.options
164
- from_options = script_opts.from_options
165
- to_options = script_opts.to_options
166
-
167
- inio = ((args.length > 0) && (args[0] != "-"))? File.open(args[0], "rb") : $stdin
168
- outio = ((args.length > 1) && (args[1] != "-"))? File.open(args[1], "wb") : $stdout
169
-
170
- HTOTConv.convert(inio, options[:from_type], outio, options[:to_type], from_options, to_options)
171
- end
172
- module_function :main
173
- end
174
- end
1
+ # frozen_string_literal: true
2
+ require 'optparse'
3
+
4
+ require 'rinne'
5
+
6
+ module HTOTConv
7
+ module CLI
8
+ class ScriptOptions
9
+ def initialize
10
+ @options = {
11
+ :from_type => :simple_text,
12
+ :to_type => :xlsx_type2,
13
+ }
14
+ @from_options = {}
15
+ @to_options = {}
16
+ end
17
+ attr_reader :options, :from_options, :to_options
18
+
19
+ def freeze
20
+ @options.freeze
21
+ @from_options.freeze
22
+ @to_options.freeze
23
+ super
24
+ end
25
+
26
+ def define_options(opts, io_filter=false)
27
+ opts.banner = %q{Hierarchical-Tree Outline Text Converter}
28
+ opts.define_head %q{Usage: htot_conv [options] [input] [output]}
29
+ opts.separator %q{}
30
+ opts.separator %q{Options:}
31
+
32
+ from_types = HTOTConv::Parser.types.map { |v| [v, v.to_s.tr("_", "-")] }.flatten
33
+ to_types = HTOTConv::Generator.types.map { |v| [v, v.to_s.tr("_", "-")] }.flatten
34
+
35
+ opts.on("-f", "--from-type=TYPE", from_types, "type of input (default: #{options[:from_type]})") do |v|
36
+ @options[:from_type] = v.to_s.tr("-", "_")
37
+ end
38
+ opts.on("-t", "--to-type=TYPE", to_types, "type of output (default: #{options[:to_type]})") do |v|
39
+ @options[:to_type] = v.to_s.tr("-", "_")
40
+ end
41
+ opts.on("-l", "--list-type", "list input/output type") do
42
+ $stdout << "type of input:\n"
43
+ $stdout << HTOTConv::Parser.types.join(" ") << "\n"
44
+ $stdout << "\n"
45
+ $stdout << "type of output:\n"
46
+ $stdout << HTOTConv::Generator.types.join(" ") << "\n"
47
+ $stdout << "\n"
48
+ exit
49
+ end
50
+
51
+ opts.separator ""
52
+ opts.on("-h", "-?", "--help", "Show this message") do
53
+ puts opts
54
+ exit
55
+ end
56
+ opts.on("--version", "Show version") do
57
+ $stdout << "htot_conv #{HTOTConv::VERSION}\n"
58
+ exit
59
+ end
60
+
61
+ opts.separator ""
62
+ opts.separator "I/O Options:"
63
+ if io_filter
64
+ define_sub_options_of(opts, HTOTConv::Parser, @options[:from_type], "from") do |key, v|
65
+ @from_options[key] = v
66
+ end
67
+ define_sub_options_of(opts, HTOTConv::Generator, @options[:to_type], "to") do |key, v|
68
+ @to_options[key] = v
69
+ end
70
+ else
71
+ define_sub_options(opts, HTOTConv::Parser, "from") do |key, v|
72
+ @from_options[key] = v
73
+ end
74
+ define_sub_options(opts, HTOTConv::Generator, "to") do |key, v|
75
+ @to_options[key] = v
76
+ end
77
+ end
78
+ end
79
+
80
+ private
81
+ def add_sub_options_of_a_type_to!(cli_options, opts, klass, type, prefix)
82
+ type_klass = klass.const_get(Rinne.camelize(type.to_s))
83
+ type_klass.option_help.each do |key,v|
84
+ long_option = "--#{prefix}-#{key.to_s.tr('_','-')}"
85
+
86
+ if cli_options.include?(long_option)
87
+ cli_options[long_option][:desc] << "For #{type}, #{v[:desc]}"
88
+ unless cli_options[long_option][:pattern] == v[:pat]
89
+ if (cli_options[long_option][:pattern].kind_of?(Array) && v[:pat].kind_of?(Array))
90
+ cli_options[long_option][:pattern] = cli_options[long_option][:pattern].concat(v[:pat]).uniq
91
+ else
92
+ raise "pattern registration mismatch around #{long_option}"
93
+ end
94
+ end
95
+ else
96
+ cli_options[long_option] = {
97
+ :key => key,
98
+ :pattern => v[:pat],
99
+ :desc => ["For #{type}, #{v[:desc]}"],
100
+ }
101
+ end
102
+ end
103
+ end
104
+
105
+ private
106
+ def define_sub_options_of(opts, klass, type, prefix) # :yields: key, v
107
+ cli_options = {}
108
+
109
+ add_sub_options_of_a_type_to!(cli_options, opts, klass, type, prefix)
110
+
111
+ cli_options.each do |long_option, value|
112
+ opts.on("#{long_option}=VAL", value[:pattern], *value[:desc]) do |v|
113
+ yield value[:key], v
114
+ end
115
+ end
116
+ end
117
+
118
+ private
119
+ def define_sub_options(opts, klass, prefix) # :yields: key, v
120
+ cli_options = {}
121
+
122
+ klass.types.each do |type|
123
+ add_sub_options_of_a_type_to!(cli_options, opts, klass, type, prefix)
124
+ end
125
+
126
+ cli_options.each do |long_option, value|
127
+ opts.on("#{long_option}=VAL", value[:pattern], *value[:desc]) do |v|
128
+ yield value[:key], v
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ def optparse!(args)
135
+ script_opts = ScriptOptions.new
136
+ OptionParser.new do |opts|
137
+ script_opts.define_options(opts)
138
+
139
+ begin
140
+ opts.parse!(args.dup)
141
+ rescue OptionParser::ParseError => ex
142
+ $stderr << ex.message << "\n"
143
+ exit 1
144
+ end
145
+ end
146
+
147
+ OptionParser.new do |opts|
148
+ script_opts.define_options(opts, true)
149
+
150
+ begin
151
+ opts.parse!(args)
152
+ rescue OptionParser::ParseError => ex
153
+ $stderr << ex.message << "\n"
154
+ exit 1
155
+ end
156
+ end
157
+ script_opts.freeze
158
+ end
159
+ module_function :optparse!
160
+
161
+ def main(args=ARGV)
162
+ script_opts = HTOTConv::CLI.optparse!(args)
163
+ options = script_opts.options
164
+ from_options = script_opts.from_options
165
+ to_options = script_opts.to_options
166
+
167
+ inio = ((args.length > 0) && (args[0] != "-"))? File.open(args[0], "rb") : $stdin
168
+ outio = ((args.length > 1) && (args[1] != "-"))? File.open(args[1], "wb") : $stdout
169
+
170
+ HTOTConv.convert(inio, options[:from_type], outio, options[:to_type], from_options, to_options)
171
+ end
172
+ module_function :main
173
+ end
174
+ end