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

|
41
|
+
|
42
|
+
## `xlsx_type1`
|
43
|
+
|
44
|
+

|
45
|
+
|
46
|
+
`--outline-rows=yes` : group rows
|
47
|
+
|
48
|
+

|
49
|
+
|
50
|
+
Not implemented (TODO):
|
51
|
+
|
52
|
+
* Fill with different background color for each level.
|
53
|
+
|
54
|
+
## `xlsx_type2`
|
55
|
+
|
56
|
+

|
57
|
+
|
58
|
+
`--integrate-cells={colspan,rowspan}` : group columns/rows.
|
59
|
+
|
60
|
+

|
61
|
+
|
62
|
+
`--outline-rows=yes` : group rows.
|
63
|
+
|
64
|
+

|
65
|
+
|
66
|
+
## `xlsx_type3`
|
67
|
+
|
68
|
+

|
69
|
+
|
70
|
+
`--integrate-cells={colspan,rowspan,both}` : group columns/rows.
|
71
|
+
|
72
|
+

|
73
|
+
|
74
|
+
## `xlsx_type4`
|
75
|
+
|
76
|
+

|
77
|
+
|
78
|
+
`--integrate-cells={colspan,rowspan,both}` : group columns/rows.
|
79
|
+
|
80
|
+

|
81
|
+
|
82
|
+
## `xlsx_type5`
|
83
|
+
|
84
|
+

|
85
|
+
|
86
|
+
`--integrate-cells=colspan` : group columns/rows.
|
87
|
+
|
88
|
+

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