htot_conv 0.3.2 → 1.0.0

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.
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