ad_hoc_template 0.4.0 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ddd8ddbfdc477efb70980b40c3e16848108df9ea
4
- data.tar.gz: fb506b375a6781451f00f32c6a88b58a2fab210c
3
+ metadata.gz: 0d886560d5c34cfc5a5db65446d0e62b71c70480
4
+ data.tar.gz: 582cba527d5ecd1e49ff8fb2a1b620c47b58cd02
5
5
  SHA512:
6
- metadata.gz: c5e5ef55188915bd037bf8b20e67b5a3226f54aa1037345510dc5a10319f4cf59711a7627c35c52c716f5633abe3170b9b6f09b56c04ec5b71a90b47c56746d9
7
- data.tar.gz: 9246fcb22fabbab24a8866ef612474121d5acc42cb4fa65a333e717aac26cc4dc7a4ebdd9d708c99eb0cdf8294fc207d98c0a43a5c69e2a2459650700dd0598d
6
+ metadata.gz: 93aa155f2b7a186c9688bd68d27af013e891f10afe73405d087dea0768cc95d73166a9adbf0c1cb7f301e2988b9357c6c30950f4a2cff24c86a9b78e214a97af
7
+ data.tar.gz: a91605ac047c69897159b0e20bae32575153f2fcf101a9aeb59ba81775eb740024e2bf4486055035d7346bb175c3b8f30edbab044c929732f525e92754f5249b
@@ -0,0 +1,23 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ Layout/SpaceInsideBlockBraces:
4
+ SpaceBeforeBlockParameters: false
5
+ Layout/SpaceAroundEqualsInParameterDefault:
6
+ EnforcedStyle: no_space
7
+ Layout/MultilineMethodCallIndentation:
8
+ EnforcedStyle: indented_relative_to_receiver
9
+ Style/ClassCheck:
10
+ EnforcedStyle: kind_of?
11
+ Style/TrailingCommaInArrayLiteral:
12
+ EnforcedStyleForMultiline: consistent_comma
13
+ Style/TrailingCommaInHashLiteral:
14
+ EnforcedStyleForMultiline: consistent_comma
15
+ Style/SpecialGlobalVars:
16
+ EnforcedStyle: use_perl_names
17
+ Documentation:
18
+ Enabled: false
19
+ Style/ParallelAssignment:
20
+ Enabled: false
21
+ Style/FrozenStringLiteralComment:
22
+ Enabled: true
23
+ EnforcedStyle: always
@@ -1,3 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
3
+ - 2.1
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - ruby-head
9
+ before_install: gem install bundler -v 1.16.1
data/Gemfile CHANGED
@@ -2,11 +2,12 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ad_hoc_template.gemspec
4
4
 
5
- gem 'pseudohikiparser', '0.0.5.develop'
5
+ gem 'pseudohikiparser', '0.0.6.develop'
6
6
  gem 'optparse_plus'
7
7
 
8
8
  group :development do
9
- gem "bundler", "~> 1.3"
9
+ gem "bundler", "~> 1.16"
10
10
  gem "rake"
11
11
  gem "rspec"
12
+ gem "rubocop", "~> 0.55"
12
13
  end
@@ -20,7 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.add_runtime_dependency "pseudohikiparser", "0.0.6.develop"
21
21
  spec.add_runtime_dependency "optparse_plus"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.3"
24
- spec.add_development_dependency "rake", "~> 10.1"
25
- spec.add_development_dependency "rspec", "~> 3.2"
23
+ spec.add_development_dependency "bundler", "~> 1.16"
24
+ spec.add_development_dependency "rake", "~> 12.3"
25
+ spec.add_development_dependency "rspec", "~> 3.7"
26
+ spec.add_development_dependency "rubocop", "~> 0.55"
26
27
  end
@@ -1,31 +1,15 @@
1
- require "ad_hoc_template/version"
2
- require "ad_hoc_template/parser"
3
- require "ad_hoc_template/record_reader"
4
- require "ad_hoc_template/default_tag_formatter"
5
- require "ad_hoc_template/pseudohiki_formatter"
6
- require "ad_hoc_template/entry_format_generator"
7
- require "ad_hoc_template/config_manager"
1
+ # frozen_string_literal: true
2
+
3
+ require 'ad_hoc_template/version'
4
+ require 'ad_hoc_template/parser'
5
+ require 'ad_hoc_template/record_reader'
6
+ require 'ad_hoc_template/default_tag_formatter'
7
+ require 'ad_hoc_template/pseudohiki_formatter'
8
+ require 'ad_hoc_template/entry_format_generator'
9
+ require 'ad_hoc_template/config_manager'
8
10
 
9
11
  module AdHocTemplate
10
12
  class DataLoader
11
- class InnerLabel
12
- attr_reader :inner_label
13
-
14
- def self.labels(inner_labels, cur_label)
15
- inner_labels.map {|label| new(label, cur_label) }
16
- end
17
-
18
- def initialize(inner_label, cur_label)
19
- @inner_label = inner_label
20
- @label, @key = inner_label.sub(/\A#/, ''.freeze).split(/\|/, 2)
21
- @cur_label = cur_label
22
- end
23
-
24
- def full_label(record)
25
- [@cur_label, @label, record[@key]].join('|')
26
- end
27
- end
28
-
29
13
  def self.format(template, record, tag_formatter=DefaultTagFormatter.new)
30
14
  if record.kind_of? Array
31
15
  return format_multi_records(template, record, tag_formatter)
@@ -40,6 +24,8 @@ module AdHocTemplate
40
24
  end.join
41
25
  end
42
26
 
27
+ attr_reader :record, :tag_formatter
28
+
43
29
  def initialize(record, tag_formatter=DefaultTagFormatter.new)
44
30
  @record = record
45
31
  @tag_formatter = tag_formatter
@@ -48,11 +34,11 @@ module AdHocTemplate
48
34
  def visit(tree, memo)
49
35
  case tree
50
36
  when Parser::IterationNode
51
- format_iteration_tag(tree, memo)
37
+ format_iteration_tag(tree, self, memo)
52
38
  when Parser::FallbackNode
53
- ''.freeze
39
+ ''
54
40
  when Parser::ValueNode
55
- format_value_tag(tree, memo)
41
+ format_value_tag(tree, self, memo)
56
42
  when Parser::Leaf
57
43
  tree.join
58
44
  else
@@ -60,51 +46,48 @@ module AdHocTemplate
60
46
  end
61
47
  end
62
48
 
63
- def format_iteration_tag(iteration_tag_node, memo)
64
- tag_node = cast(iteration_tag_node)
49
+ def format_iteration_tag(iteration_tag_node, data_loader, memo)
50
+ tag_node = iteration_tag_node.cast
65
51
 
66
- prepare_sub_records(iteration_tag_node).map do |record|
67
- if tag_node.contains_any_value_assigned_tag_node?(record)
68
- visit_with_sub_record(tag_node, record, memo)
69
- elsif fallback_nodes = select_fallback_nodes(tag_node)
70
- format_fallback_tags(fallback_nodes, record, memo)
71
- else
72
- "".freeze
73
- end
52
+ prepare_sub_records(iteration_tag_node, data_loader).map do |record|
53
+ format_sub_nodes(tag_node, record, data_loader, memo)
74
54
  end
75
55
  end
76
56
 
77
- def format_value_tag(tag_node, memo)
78
- leafs = tag_node.map {|leaf| leaf.accept(self, memo) }
79
- @tag_formatter.format(tag_node.type, leafs.join.strip, @record)
57
+ def format_value_tag(tag_node, data_loader, memo)
58
+ leafs = tag_node.format_sub_nodes(data_loader, memo).strip
59
+ data_loader.tag_formatter.format(tag_node.type, leafs, data_loader.record)
80
60
  end
81
61
 
82
62
  def format(tree, memo=nil)
83
63
  tree.accept(self, memo).join
84
64
  end
85
65
 
86
- private
66
+ def new_with_record(record)
67
+ self.class.new(record, @tag_formatter)
68
+ end
87
69
 
88
- def cast(node, node_type=Parser::TagNode)
89
- node_type.new.concat(node.clone)
70
+ protected
71
+
72
+ def sub_records(tag_node)
73
+ @record[tag_node.type] || [@record]
90
74
  end
91
75
 
92
- def prepare_sub_records(tag_node)
93
- cur_label = tag_node.type
94
- sub_records = @record[cur_label]||[@record]
95
- return sub_records unless cur_label
96
- inner_labels = tag_node.inner_iteration_tag_labels
97
- return sub_records unless inner_labels
98
- inner_labels = InnerLabel.labels(inner_labels, cur_label)
99
- sub_records.map do |record|
100
- prepare_inner_iteration_records(record, inner_labels)
76
+ private
77
+
78
+ def prepare_sub_records(tag_node, data_loader)
79
+ inner_labels = tag_node.inner_labels
80
+ return data_loader.sub_records(tag_node) unless inner_labels
81
+ data_loader.sub_records(tag_node).map do |record|
82
+ merge_inner_iteration_records(record, inner_labels, data_loader)
101
83
  end
102
84
  end
103
85
 
104
- def prepare_inner_iteration_records(record, inner_labels)
86
+ def merge_inner_iteration_records(record, inner_labels, data_loader)
105
87
  new_record = nil
106
88
  inner_labels.each do |label|
107
- if inner_data = @record[label.full_label(record)]
89
+ inner_data = data_loader.record[label.full_label(record)]
90
+ if inner_data
108
91
  new_record ||= record.dup
109
92
  new_record[label.inner_label] = inner_data
110
93
  end
@@ -112,27 +95,26 @@ module AdHocTemplate
112
95
  new_record || record
113
96
  end
114
97
 
115
- def visit_with_sub_record(tag_node, record, memo)
116
- data_loader = AdHocTemplate::DataLoader.new(record, @tag_formatter)
117
- tag_node.map {|leaf| leaf.accept(data_loader, memo) }.join
118
- end
119
-
120
- def select_fallback_nodes(tag_node)
121
- tags = tag_node.select {|sub_node| sub_node.kind_of? Parser::FallbackNode }
122
- tags.empty? ? nil : tags
98
+ def format_sub_nodes(tag_node, record, data_loader, memo)
99
+ if tag_node.contains_any_value_assigned_tag_node?(record)
100
+ tag_node.format_sub_nodes(data_loader.new_with_record(record), memo)
101
+ elsif tag_node.contains_any_fallback_tag?
102
+ format_fallback_tags(tag_node.select_fallback_nodes,
103
+ data_loader.new_with_record(record), memo)
104
+ else
105
+ ''
106
+ end
123
107
  end
124
108
 
125
- def format_fallback_tags(fallback_nodes, record, memo)
126
- data_loader = AdHocTemplate::DataLoader.new(record, @tag_formatter)
109
+ def format_fallback_tags(fallback_nodes, data_loader, memo)
127
110
  fallback_nodes.map do |fallback_node|
128
- node = cast(fallback_node, Parser::IterationNode)
129
- node.contains_any_value_tag? ? node.accept(data_loader, memo) : node.join
111
+ fallback_node.format_sub_nodes(data_loader, memo)
130
112
  end
131
113
  end
132
114
  end
133
115
 
134
- def self.render(record_data, template, tag_type=:default, data_format=:default,
135
- tag_formatter=DefaultTagFormatter.new)
116
+ def self.render(record_data, template, tag_type=:default,
117
+ data_format=:default, tag_formatter=DefaultTagFormatter.new)
136
118
  tree = Parser.parse(template, tag_type)
137
119
  record = RecordReader.read_record(record_data, data_format)
138
120
  DataLoader.format(tree, record, tag_formatter)
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'ad_hoc_template'
4
4
  require 'optparse_plus'
@@ -11,7 +11,8 @@ AdHocTemplate::ConfigManager.require_local_settings
11
11
  module AdHocTemplate
12
12
  class CommandLineInterface
13
13
  include Utils
14
- attr_accessor :output_filename, :template_data, :record_data, :tag_type, :data_format
14
+ attr_accessor :output_filename, :tag_type, :data_format,
15
+ :template_data, :record_data
15
16
  attr_writer :output_empty_entry
16
17
 
17
18
  TAG_RE_TO_TYPE = {
@@ -21,15 +22,15 @@ module AdHocTemplate
21
22
  /\Axml_like1/i => :xml_like1,
22
23
  /\Axml_like2/i => :xml_like2,
23
24
  /\Axml_comment_like/i => :xml_comment_like,
24
- }
25
+ }.freeze
25
26
 
26
- FORMAT_RE_TO_FORMAT = {
27
+ RE_TO_FORMAT = {
27
28
  /\Ad(efault)?/i => :default,
28
29
  /\Ay(a?ml)?/i => :yaml,
29
30
  /\Aj(son)?/i => :json,
30
31
  /\Ac(sv)?/i => :csv,
31
32
  /\At(sv)?/i => :tsv,
32
- }
33
+ }.freeze
33
34
 
34
35
  def initialize
35
36
  @tag_formatter = AdHocTemplate::DefaultTagFormatter.new
@@ -37,6 +38,7 @@ module AdHocTemplate
37
38
  @tag_type = :default
38
39
  @data_format = nil
39
40
  @force_update = false
41
+ @init_local_settings = false
40
42
  end
41
43
 
42
44
  def parse_command_line_options
@@ -45,11 +47,11 @@ module AdHocTemplate
45
47
  opt.version = AdHocTemplate::VERSION
46
48
 
47
49
  opt.inherit_ruby_options('E') # -E, --encoding
48
- opt.on(:output_file) {|output_file| @output_filename = File.expand_path(output_file) }
50
+ opt.on(:output_file) {|file| @output_filename = File.expand_path(file) }
49
51
  opt.on(:tag_type) {|given_type| choose_tag_type(given_type) }
50
52
  opt.on(:data_format) {|data_format| choose_data_format(data_format) }
51
- opt.on(:tag_config) {|tag_config_yaml| register_user_defined_tag_type(tag_config_yaml) }
52
- opt.on(:entry_format) {|entry_format| @output_empty_entry = true }
53
+ opt.on(:tag_config) {|yaml| register_user_defined_tag_type(yaml) }
54
+ opt.on(:entry_format) { @output_empty_entry = true }
53
55
  opt.on(:init_local_settings) { init_local_settings }
54
56
  opt.on(:recipe_template) { @output_recipe_template = true }
55
57
  opt.on(:cooking_recipe) {|recipe_yaml| @recipe_yaml = recipe_yaml }
@@ -60,7 +62,7 @@ module AdHocTemplate
60
62
 
61
63
  unless @data_format
62
64
  guessed_format = ARGV.length < 2 ? :default : guess_file_format(ARGV[1])
63
- @data_format = guessed_format || :default
65
+ @data_format = guessed_format || :default
64
66
  end
65
67
  end
66
68
 
@@ -69,7 +71,7 @@ module AdHocTemplate
69
71
  if template
70
72
  @template_data = File.read(template)
71
73
  else
72
- STDERR.puts "No template file is given."
74
+ STDERR.puts 'No template file is given.'
73
75
  end
74
76
 
75
77
  @record_data = record ? File.read(record) : ARGF.read
@@ -77,7 +79,7 @@ module AdHocTemplate
77
79
 
78
80
  def render
79
81
  AdHocTemplate.render(@record_data, @template_data, @tag_type,
80
- @data_format, @tag_formatter)
82
+ @data_format, @tag_formatter)
81
83
  end
82
84
 
83
85
  def generate_entry_format
@@ -87,28 +89,25 @@ module AdHocTemplate
87
89
 
88
90
  def init_local_settings
89
91
  AdHocTemplate::ConfigManager.init_local_settings
90
- config_dir = File.expand_path(AdHocTemplate::ConfigManager::LOCAL_SETTINGS_DIR)
92
+ config_dir = ConfigManager.expand_path('')
91
93
  puts "Please edit configuration files created in #{config_dir}"
92
- exit
94
+ @init_local_settings = true
93
95
  end
94
96
 
95
97
  def generate_recipe_template(templates)
96
98
  encoding = Encoding.default_external.names[0]
97
- AdHocTemplate::EntryFormatGenerator.
98
- extract_recipes_from_template_files(templates,
99
- @tag_type)
99
+ AdHocTemplate::EntryFormatGenerator
100
+ .extract_recipes_from_template_files(templates, @tag_type, encoding)
100
101
  end
101
102
 
102
103
  def update_output_files_in_recipe(recipe)
103
- AdHocTemplate::RecipeManager.update_output_files_in_recipe(recipe,
104
- @force_update)
104
+ AdHocTemplate::RecipeManager
105
+ .update_output_files_in_recipe(recipe, @force_update)
105
106
  end
106
107
 
107
108
  def open_output
108
109
  if @output_filename
109
- open(@output_filename, "wb") do |out|
110
- yield out
111
- end
110
+ File.open(@output_filename, 'wb') {|out| yield out }
112
111
  else
113
112
  yield STDOUT
114
113
  end
@@ -116,34 +115,35 @@ module AdHocTemplate
116
115
 
117
116
  def execute
118
117
  parse_command_line_options
118
+ exit if @init_local_settings
119
119
  return update_output_files_in_recipe(@recipe_yaml) if @recipe_yaml
120
120
  read_input_files
121
- output = if @output_empty_entry
122
- generate_entry_format
123
- elsif @output_recipe_template
124
- generate_recipe_template(ARGV)
125
- else
126
- render
127
- end
128
- open_output {|out| out.print output }
121
+ open_output {|out| out.print generate_output }
129
122
  end
130
123
 
131
124
  private
132
125
 
126
+ def generate_output
127
+ return generate_entry_format if @output_empty_entry
128
+ return generate_recipe_template(ARGV) if @output_recipe_template
129
+ render
130
+ end
131
+
133
132
  def choose_tag_type(given_type)
134
- err_msg = "The given type is not found. The default tag is chosen."
133
+ err_msg = 'The given type is not found. The default tag is chosen.'
135
134
 
136
- if_any_regex_match(TAG_RE_TO_TYPE, given_type, err_msg) do |re, tag_type|
135
+ if_any_regex_match(TAG_RE_TO_TYPE, given_type, err_msg) do |_, tag_type|
137
136
  @tag_type = tag_type
138
137
  end
139
138
  end
140
139
 
141
140
  def choose_data_format(data_format)
142
- err_msg = "The given format is not found. The default format is chosen."
141
+ err_msg = 'The given format is not found. The default format is chosen.'
143
142
  format_part, label_part = data_format.split(/:/, 2)
144
143
 
145
- if_any_regex_match(FORMAT_RE_TO_FORMAT, format_part, err_msg) do |re, format|
146
- @data_format = [:csv, :tsv].include?(format) ? make_csv_option(label_part, format) : format
144
+ if_any_regex_match(RE_TO_FORMAT, format_part, err_msg) do |_, format|
145
+ csv_with_label = value_assigned?(label_part) && csv_or_tsv?(format)
146
+ @data_format = csv_with_label ? { format => label_part } : format
147
147
  end
148
148
  end
149
149
 
@@ -152,9 +152,8 @@ module AdHocTemplate
152
152
  @tag_type = Parser.register_user_defined_tag_type(config)
153
153
  end
154
154
 
155
- def make_csv_option(iteration_label, format)
156
- return format if iteration_label.nil? or iteration_label.empty?
157
- { format => iteration_label }
155
+ def value_assigned?(iteration_label)
156
+ !(iteration_label.nil? || iteration_label.empty?)
158
157
  end
159
158
  end
160
159
  end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'fileutils'
4
4
 
@@ -12,9 +12,7 @@ module AdHocTemplate
12
12
 
13
13
  def self.require_local_settings
14
14
  settings_file = File.expand_path(LOCAL_SETTINGS_FILE)
15
- if File.exist? settings_file
16
- require settings_file
17
- end
15
+ require settings_file if File.exist? settings_file
18
16
  end
19
17
 
20
18
  def self.configure(&config_block)
@@ -44,18 +42,15 @@ module AdHocTemplate
44
42
  end
45
43
 
46
44
  def self.expand_path(path)
47
- unless /\A[\.\/]/ =~ path
48
- path = File.join(LOCAL_SETTINGS_DIR, path)
49
- end
45
+ path = File.join(LOCAL_SETTINGS_DIR, path) unless %r{\A[\./]} =~ path
50
46
  File.expand_path(path)
51
47
  end
52
48
 
53
49
  def self.create_unless_exist(path, content)
54
50
  return if File.exist? path
55
- open(path, "w") {|file| file.print content }
51
+ File.open(path, 'wb') {|file| file.print content }
56
52
  end
57
53
 
58
- private_class_method :expand_path
59
54
  private_class_method :create_unless_exist
60
55
 
61
56
  @local_settings_template = <<SETTING_TEMPLATE
@@ -117,7 +112,7 @@ AdHocTemplate.local_settings do
117
112
  end
118
113
  SETTING_TEMPLATE
119
114
 
120
- @custom_tag_template =<<TAG_TEMPLATE
115
+ @custom_tag_template = <<TAG_TEMPLATE
121
116
  ---
122
117
  tag_name: :default
123
118
  tag: ["<%", "%>"]