docbook_files 0.4.0 → 0.5.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.
- data/Gemfile +12 -4
- data/Gemfile.lock +9 -4
- data/History.txt +10 -0
- data/LICENSE +22 -0
- data/README.md +30 -18
- data/Rakefile +15 -1
- data/lib/docbook_files/app.rb +112 -79
- data/lib/docbook_files/docbook.rb +2 -2
- data/lib/docbook_files/file_data.rb +125 -83
- data/lib/docbook_files/file_ref.rb +98 -0
- data/lib/docbook_files/file_ref_types.rb +20 -0
- data/spec/docbook_files/app_spec.rb +69 -15
- data/spec/docbook_files/docbook_spec.rb +1 -1
- data/spec/docbook_files/file_data_spec.rb +59 -49
- data/spec/docbook_files/file_ref_spec.rb +97 -0
- data/version.txt +1 -1
- metadata +49 -16
data/Gemfile
CHANGED
@@ -3,14 +3,22 @@ source "http://rubygems.org"
|
|
3
3
|
gem "libxml-ruby", :require => 'xml'
|
4
4
|
gem "term-ansicolor"
|
5
5
|
gem "wand"
|
6
|
-
gem "
|
6
|
+
gem "zucker"
|
7
|
+
gem "json", :platforms => :ruby_18
|
8
|
+
gem "win32console", :platforms => :mingw
|
7
9
|
|
8
10
|
group :development do
|
9
11
|
gem "bones"
|
10
|
-
gem 'turn'
|
11
12
|
gem 'rspec'
|
12
13
|
gem 'guard'
|
13
|
-
gem 'rb-fsevent'
|
14
|
-
gem 'growl_notify'
|
15
14
|
gem 'guard-rspec'
|
16
15
|
end
|
16
|
+
group :darwin do
|
17
|
+
gem 'rb-fsevent', :require => false
|
18
|
+
gem 'growl_notify', :require => false
|
19
|
+
end
|
20
|
+
group :linux do
|
21
|
+
gem 'rb-inotify', :require => false
|
22
|
+
gem 'libnotify', :require => false
|
23
|
+
end
|
24
|
+
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
ansi (1.3.0)
|
5
4
|
bones (3.7.1)
|
6
5
|
little-plugger (>= 1.1.2)
|
7
6
|
loquacious (>= 1.8.1)
|
8
7
|
rake (>= 0.8.7)
|
9
8
|
diff-lcs (1.1.3)
|
9
|
+
ffi (1.0.9)
|
10
10
|
growl_notify (0.0.3)
|
11
11
|
rb-appscript
|
12
12
|
guard (0.8.4)
|
@@ -14,6 +14,7 @@ GEM
|
|
14
14
|
guard-rspec (0.5.0)
|
15
15
|
guard (>= 0.8.4)
|
16
16
|
json (1.6.1)
|
17
|
+
libnotify (0.5.7)
|
17
18
|
libxml-ruby (2.2.2)
|
18
19
|
little-plugger (1.1.2)
|
19
20
|
loquacious (1.9.0)
|
@@ -21,6 +22,8 @@ GEM
|
|
21
22
|
rake (0.9.2)
|
22
23
|
rb-appscript (0.6.1)
|
23
24
|
rb-fsevent (0.4.3.1)
|
25
|
+
rb-inotify (0.8.8)
|
26
|
+
ffi (>= 0.5.0)
|
24
27
|
rspec (2.6.0)
|
25
28
|
rspec-core (~> 2.6.0)
|
26
29
|
rspec-expectations (~> 2.6.0)
|
@@ -32,11 +35,10 @@ GEM
|
|
32
35
|
safe_shell (1.0.1)
|
33
36
|
term-ansicolor (1.0.7)
|
34
37
|
thor (0.14.6)
|
35
|
-
turn (0.8.3)
|
36
|
-
ansi
|
37
38
|
wand (0.4)
|
38
39
|
mime-types
|
39
40
|
safe_shell (~> 1.0.0)
|
41
|
+
zucker (11)
|
40
42
|
|
41
43
|
PLATFORMS
|
42
44
|
ruby
|
@@ -47,9 +49,12 @@ DEPENDENCIES
|
|
47
49
|
guard
|
48
50
|
guard-rspec
|
49
51
|
json
|
52
|
+
libnotify
|
50
53
|
libxml-ruby
|
51
54
|
rb-fsevent
|
55
|
+
rb-inotify
|
52
56
|
rspec
|
53
57
|
term-ansicolor
|
54
|
-
turn
|
55
58
|
wand
|
59
|
+
win32console
|
60
|
+
zucker
|
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.5.0 / 2011-10-19
|
2
|
+
|
3
|
+
* A file can now manage multiple inclusions and/or references.
|
4
|
+
* The YAML and JSON output contains now two sections, hierarchy and details, just like the terminal output.
|
5
|
+
* The details contain new fields for multiple references: includes, included_by and references, referenced_by
|
6
|
+
|
7
|
+
* Minor changes
|
8
|
+
** Removed JSON dependency. It is used when available.
|
9
|
+
** Color support is now optional on Windows
|
10
|
+
|
1
11
|
== 0.4.0 / 2011-10-14
|
2
12
|
|
3
13
|
* Added JSON and YAML output formats
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Rainer Volz
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -29,29 +29,41 @@ If you don't like the screen output or want to integrate docbook_file into a cer
|
|
29
29
|
|
30
30
|
docbook_files --outputformat=yaml myproject.xml
|
31
31
|
|
32
|
-
The result is printed to STDOUT. The structure returned is equivalent to the normal terminal output, except that you always get the details.
|
33
|
-
|
34
|
-
*
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
*
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
32
|
+
The result is printed to STDOUT. The structure returned is equivalent to the normal terminal output, except that you always get the details.
|
33
|
+
|
34
|
+
* hierarchy - an array of entries for each step in the file hierarchy
|
35
|
+
** type - file type (main, inc-luded, or ref-erenced)
|
36
|
+
** name - file name
|
37
|
+
** path - path relative to the main file
|
38
|
+
** status - error status: 0 = ok, 1 = file not found, 2 = processing error (see error_string)
|
39
|
+
** size - file size in bytes
|
40
|
+
** level - the level in the file hierarchy, starting with 0
|
41
|
+
|
42
|
+
* details - an array of entries for each file used in the hierarchy
|
43
|
+
** name - file name
|
44
|
+
** path - path relative to the main file
|
45
|
+
** status - error status: 0 = ok, 1 = file not found, 2 = processing error (see error_string)
|
46
|
+
** error_string - contains an error message, if status > 0
|
47
|
+
** namespace - XML namespace, if applicable
|
48
|
+
** version - XML version attribute, if applicable
|
49
|
+
** docbook - true for DocBook 5 files, else false
|
50
|
+
** tag - start tag for XML files (chapter, book, article ...)
|
51
|
+
** ts - file modification time
|
52
|
+
** size - file size in byte
|
53
|
+
** checksum - SHA1 checksum
|
54
|
+
** mime - MIME type
|
55
|
+
** includes - files that are included by this file, an array of file names
|
56
|
+
** included_by - files that include this file, an array of file names
|
57
|
+
** references - files that are referenced by this file, an array of file names
|
58
|
+
** referenced_by - files that reference this file, an array of file names
|
59
|
+
|
50
60
|
|
51
61
|
Requirements
|
52
62
|
------------
|
53
63
|
|
54
64
|
* libxml2
|
65
|
+
* json (optional, if you want JSON output on Ruby 1.8)
|
66
|
+
* win32console (optional, if you want color support on MS Windows)
|
55
67
|
|
56
68
|
Install
|
57
69
|
-------
|
data/Rakefile
CHANGED
@@ -21,5 +21,19 @@ Bones {
|
|
21
21
|
depend_on 'libxml-ruby'
|
22
22
|
depend_on 'term-ansicolor'
|
23
23
|
depend_on 'wand'
|
24
|
-
depend_on '
|
24
|
+
depend_on 'zucker'
|
25
|
+
depend_on 'rspec', :development => true
|
26
|
+
gem.extras[:license] = 'MIT'
|
27
|
+
gem.extras[:post_install_message] = <<-POST_INSTALL_MSG
|
28
|
+
|
29
|
+
Please note:
|
30
|
+
|
31
|
+
- docbook_files uses color to mark problematic files.
|
32
|
+
On Windows, you should additionally install the gem 'win32console'
|
33
|
+
to enable color output in the terminal.
|
34
|
+
|
35
|
+
- JSON output is optional for Ruby 1.8. Please install the gem 'json'
|
36
|
+
if you are running Ruby 1.8 and want JSON output.
|
37
|
+
|
38
|
+
POST_INSTALL_MSG
|
25
39
|
}
|
data/lib/docbook_files/app.rb
CHANGED
@@ -2,21 +2,48 @@
|
|
2
2
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'yaml'
|
5
|
-
require '
|
6
|
-
require 'term/ansicolor'
|
5
|
+
require 'zucker/env'
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
# Windows (RubyInstaller) needs the additional gem.
|
8
|
+
# If not present create dummies for the color routines.
|
9
|
+
if OS.windows?
|
10
|
+
begin
|
11
|
+
require 'win32console'
|
12
|
+
require 'term/ansicolor'
|
13
|
+
class String
|
14
|
+
include Term::ANSIColor
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
class String
|
18
|
+
def red; self; end
|
19
|
+
def green; self; end
|
20
|
+
def magenta; self; end
|
21
|
+
def bold; self; end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
require 'term/ansicolor'
|
26
|
+
class String
|
27
|
+
include Term::ANSIColor
|
28
|
+
end
|
10
29
|
end
|
11
30
|
|
12
31
|
module DocbookFiles
|
13
32
|
|
14
33
|
# Create a new instance of App, and run the +docbook_files+ application given
|
15
|
-
# the command line _args_.
|
34
|
+
# the command line _args_. Check also for JSON availability.
|
16
35
|
#
|
17
36
|
def self.run( args = nil )
|
18
37
|
args ||= ARGV.dup.map! { |v| v.dup }
|
19
|
-
|
38
|
+
opts = {}
|
39
|
+
# For Windows and/or Ruby 1.8
|
40
|
+
begin
|
41
|
+
require 'json'
|
42
|
+
opts[:json_available] = true
|
43
|
+
rescue LoadError
|
44
|
+
opts[:json_available] = false
|
45
|
+
end
|
46
|
+
::DocbookFiles::App.new(opts).run args
|
20
47
|
end
|
21
48
|
|
22
49
|
##
|
@@ -28,6 +55,14 @@ module DocbookFiles
|
|
28
55
|
# * 2 - processing error
|
29
56
|
#
|
30
57
|
class App
|
58
|
+
|
59
|
+
# Replacement for empty values
|
60
|
+
EMPTYVAL = '-'
|
61
|
+
|
62
|
+
# Replacement for monstrously large files sizes
|
63
|
+
XXL_SIZE = "XXL"
|
64
|
+
|
65
|
+
# Help banner
|
31
66
|
@@banner = <<EOB
|
32
67
|
docbook_files, Version #{DocbookFiles::VERSION}
|
33
68
|
|
@@ -37,6 +72,7 @@ Files with problems (not found, invalid ...) are marked red.
|
|
37
72
|
Usage: docbook_files [options] <DOCBOOK-FILE>
|
38
73
|
EOB
|
39
74
|
|
75
|
+
# Initialize options and reset the FileData storage
|
40
76
|
def initialize(opts = {})
|
41
77
|
opts[:stdout] ||= $stdout
|
42
78
|
opts[:stderr] ||= $stderr
|
@@ -45,22 +81,28 @@ EOB
|
|
45
81
|
@stderr = opts[:stderr]
|
46
82
|
@opts[:output_format] ||= :screen
|
47
83
|
@opts[:details] ||= false
|
48
|
-
@
|
49
|
-
|
84
|
+
@opts[:json_available] ||= opts[:json_available]
|
85
|
+
@props = [:name, :path, :status, :size]
|
86
|
+
FileData.reset()
|
50
87
|
end
|
51
88
|
|
52
89
|
def run(args)
|
53
90
|
opts = OptionParser.new
|
54
91
|
opts.on('--details','List file details') {|val| @opts[:details] = true}
|
55
|
-
opts.on('--outputformat=yaml|json',['
|
92
|
+
opts.on('--outputformat=yaml|json',['yaml','json'],
|
56
93
|
'Return the result in YAML or JSON format') {|format|
|
57
94
|
case
|
58
95
|
when format == 'yaml'
|
59
96
|
@opts[:output_format] = :yaml
|
60
97
|
when format == 'json'
|
61
|
-
@opts[:
|
98
|
+
if @opts[:json_available]
|
99
|
+
@opts[:output_format] = :json
|
100
|
+
else
|
101
|
+
@stderr.puts "Error: JSON not available. Please install the json gem first."
|
102
|
+
exit 1
|
103
|
+
end
|
62
104
|
else
|
63
|
-
@stderr.puts "
|
105
|
+
@stderr.puts "Error: Unknown output format #{format}."
|
64
106
|
end
|
65
107
|
}
|
66
108
|
opts.banner = @@banner
|
@@ -83,6 +125,7 @@ EOB
|
|
83
125
|
begin
|
84
126
|
dbf = DocbookFiles::Docbook.new(rest[0])
|
85
127
|
table = dbf.list_as_table(@props)
|
128
|
+
files = FileData.files
|
86
129
|
rescue => exc
|
87
130
|
@stderr.puts "Something unexpected happend while docbook_files was running ..."
|
88
131
|
@stderr.puts exc.inspect.red
|
@@ -91,27 +134,29 @@ EOB
|
|
91
134
|
unless table.nil?
|
92
135
|
case @opts[:output_format]
|
93
136
|
when :json
|
94
|
-
|
95
|
-
|
96
|
-
t[:full_name] = relative2main(t[:full_name], mpath)
|
97
|
-
t
|
98
|
-
}
|
99
|
-
@stdout.puts ntable.to_json
|
137
|
+
out = {:hierarchy => table, :details => files2table(files)}
|
138
|
+
@stdout.puts out.to_json
|
100
139
|
when :yaml
|
101
|
-
|
102
|
-
|
103
|
-
t[:full_name] = relative2main(t[:full_name], mpath)
|
104
|
-
t
|
105
|
-
}
|
106
|
-
YAML.dump(ntable,@stdout)
|
140
|
+
out = {:hierarchy => table, :details => files2table(files)}
|
141
|
+
YAML.dump(out,@stdout)
|
107
142
|
else
|
108
|
-
|
143
|
+
output_hierarchy(table)
|
144
|
+
output_details(files) if @opts[:details]
|
109
145
|
end
|
110
146
|
end
|
111
147
|
end
|
112
148
|
|
113
|
-
#
|
114
|
-
def
|
149
|
+
# Transform the files into something YAML/JSON can handle
|
150
|
+
def files2table(files)
|
151
|
+
files.map { |f|
|
152
|
+
f.to_hash([:name, :path, :status, :error_string, :namespace,
|
153
|
+
:version, :docbook, :tag, :ts, :size, :checksum,
|
154
|
+
:mime, :includes, :included_by, :references, :referenced_by])
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
# Terminal output for file hierarchy
|
159
|
+
def output_hierarchy(table)
|
115
160
|
output_string = "%3d %-60s %4s %10s"
|
116
161
|
@stdout.puts
|
117
162
|
@stdout.puts 'File Hierarchy'.bold
|
@@ -122,7 +167,7 @@ EOB
|
|
122
167
|
sum_xml_err = 0
|
123
168
|
table.each do |t|
|
124
169
|
output = output_string % [t[:level],
|
125
|
-
format_name(t[:level],t[:
|
170
|
+
format_name(t[:level],t[:path]),
|
126
171
|
t[:type].to_s,
|
127
172
|
format_size(t[:size])]
|
128
173
|
sum_size += t[:size]
|
@@ -145,36 +190,44 @@ EOB
|
|
145
190
|
summary += " #{sum_xml_err} file(s) with errors.".red
|
146
191
|
end
|
147
192
|
@stdout.puts summary
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
193
|
+
end
|
194
|
+
|
195
|
+
# Print the FileData representation to the terminal
|
196
|
+
def output_details(files)
|
197
|
+
@stdout.puts
|
198
|
+
@stdout.puts "Details".bold
|
199
|
+
files.each do |t|
|
200
|
+
fname = t.path
|
201
|
+
@stdout.puts "File: %s" % [((t.status == FileData::STATUS_OK) ? fname : fname.red)]
|
202
|
+
@stdout.puts "Includes: %s" % [format_fds(t.includes)] unless t.includes.empty?
|
203
|
+
@stdout.puts "Included by: %s" % [format_fds(t.included_by)] unless t.included_by.empty?
|
204
|
+
@stdout.puts "References: %s" % [format_fds(t.references)] unless t.references.empty?
|
205
|
+
@stdout.puts "Referenced by: %s" % [format_fds(t.referenced_by)] unless t.referenced_by.empty?
|
206
|
+
unless t.status == FileData::STATUS_NOT_FOUND
|
207
|
+
# show that part only if file exists
|
208
|
+
@stdout.puts "Size: %s (%d)" % [format_size(t.size),t.size]
|
209
|
+
if (t.docbook)
|
210
|
+
@stdout.puts "Type: DocBook, Version #{t.version}, Tag: #{t.tag}"
|
158
211
|
else
|
159
|
-
@stdout.puts "
|
160
|
-
end
|
161
|
-
unless t[:status] == FileData::STATUS_NOT_FOUND
|
162
|
-
# show that part only if file exists
|
163
|
-
@stdout.puts "Size: %s (%d)" % [format_size(t[:size]),t[:size]]
|
164
|
-
if (t[:docbook])
|
165
|
-
@stdout.puts "Type: DocBook, Version #{t[:version]}, Tag: #{t[:tag]}"
|
166
|
-
else
|
167
|
-
@stdout.puts "MIME: #{val_s(t[:mime])}"
|
168
|
-
end
|
169
|
-
@stdout.puts "Timestamp: %s" % [t[:ts]]
|
170
|
-
@stdout.puts "Checksum: %s" % [t[:checksum]]
|
212
|
+
@stdout.puts "MIME: #{val_s(t.mime)}"
|
171
213
|
end
|
172
|
-
@stdout.puts "
|
173
|
-
@stdout.puts
|
214
|
+
@stdout.puts "Timestamp: %s" % [t.ts]
|
215
|
+
@stdout.puts "SHA1: %s" % [t.checksum]
|
174
216
|
end
|
217
|
+
@stdout.puts "Error: %s" % [t.error_string.to_s.red] unless (t.error_string.nil?)
|
218
|
+
@stdout.puts
|
175
219
|
end
|
176
220
|
end
|
177
221
|
|
222
|
+
|
223
|
+
# Format a list of FileDatas
|
224
|
+
def format_fds(fds)
|
225
|
+
if (fds.nil? || fds.empty?)
|
226
|
+
EMPTYVAL
|
227
|
+
else
|
228
|
+
fds.map {|p| p.path}.join ','
|
229
|
+
end
|
230
|
+
end
|
178
231
|
|
179
232
|
# Format the filename to indicate the level in the hierarchy.
|
180
233
|
# Indentation = two spaces per level.
|
@@ -183,9 +236,8 @@ EOB
|
|
183
236
|
# relative part of the path is shown, else the full path.
|
184
237
|
# If the resulting string is too long for display it is shortened.
|
185
238
|
#
|
186
|
-
def format_name(level, full_name
|
187
|
-
|
188
|
-
lnname = ' '*level+nname
|
239
|
+
def format_name(level, full_name)
|
240
|
+
lnname = ' '*level+full_name
|
189
241
|
if (lnname.length > 60)
|
190
242
|
lnname[0..3]+'...'+lnname[-54,lnname.length-1]
|
191
243
|
else
|
@@ -193,18 +245,6 @@ EOB
|
|
193
245
|
end
|
194
246
|
end
|
195
247
|
|
196
|
-
# Try to find the path of _file_name_ that is relative to the _main file_.
|
197
|
-
# If there is no common part return the _file_name_.
|
198
|
-
def relative2main(file_name,main_name)
|
199
|
-
main_dir = File.dirname(main_name)
|
200
|
-
md = file_name.match("^#{main_dir}/")
|
201
|
-
if md.nil?
|
202
|
-
file_name
|
203
|
-
else
|
204
|
-
md.post_match
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
248
|
# :stopdoc:
|
209
249
|
KB = 1024
|
210
250
|
MB = 1048576
|
@@ -217,7 +257,7 @@ EOB
|
|
217
257
|
# Sizes >= 1PB will return 'XXL'
|
218
258
|
def format_size(sz)
|
219
259
|
if (emptyval?(sz))
|
220
|
-
|
260
|
+
EMPTYVAL
|
221
261
|
else
|
222
262
|
case
|
223
263
|
when sz < KB then "#{sz}B"
|
@@ -226,18 +266,14 @@ EOB
|
|
226
266
|
when sz >= GB && sz < TB then "#{sz/GB}GB"
|
227
267
|
when sz >= TB && sz < PB then "#{sz/TB}TB"
|
228
268
|
else
|
229
|
-
|
269
|
+
XXL_SIZE
|
230
270
|
end
|
231
271
|
end
|
232
272
|
end
|
233
273
|
|
234
|
-
# Return a string for the value, '
|
274
|
+
# Return a string for the value, '-' if there is none.
|
235
275
|
def val_s(val)
|
236
|
-
|
237
|
-
'-'
|
238
|
-
else
|
239
|
-
val.to_s
|
240
|
-
end
|
276
|
+
emptyval?(val) ? EMPTYVAL : val.to_s
|
241
277
|
end
|
242
278
|
|
243
279
|
# Check whether the value is nil or empty.
|
@@ -245,12 +281,9 @@ EOB
|
|
245
281
|
if val.nil?
|
246
282
|
true
|
247
283
|
else
|
248
|
-
|
249
|
-
val.empty?
|
250
|
-
else
|
251
|
-
false
|
252
|
-
end
|
284
|
+
(val.class == String) ? val.empty? : false
|
253
285
|
end
|
254
286
|
end
|
287
|
+
|
255
288
|
end
|
256
289
|
end
|