mrtable 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 96ed9a18eb27745d6768ec317b07556ae131eb54
4
+ data.tar.gz: 98d67db991cb936f04c70eb43b018a60245b01bc
5
+ SHA512:
6
+ metadata.gz: b9dbcbdb67aecd85089041986b2f29a7aac7b4676e68cb31e65a175ed5ba08fcf5d725bd89599118fc7ba4667ffc99e07045fbc086109d3b333ef72d18eb4fee
7
+ data.tar.gz: e8e1c9ccc929859fe482469c7d0850a5d15146af4c132caa6d7a5d746390572ca308baf18b80ed6c25148546c9170873697f86f7c9f20053ee04e0191ac0ff6b
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ # Bundler
2
+
3
+ /.bundle/
4
+ /Gemfile.lock
5
+ /vendor/
6
+ /pkg/
7
+
8
+ # Emacs
9
+
10
+ *~
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mrtable.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # Mrtable
2
+
3
+ Machine readable table.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mrtable'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mrtable
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
data/Rakefile ADDED
@@ -0,0 +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
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mrtable"
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 ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install --path=vendor/bundle
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,3 @@
1
+ module Mrtable
2
+ VERSION = "0.0.1"
3
+ end
data/lib/mrtable.rb ADDED
@@ -0,0 +1,217 @@
1
+ # coding: utf-8
2
+
3
+ require "mrtable/version"
4
+ require "json"
5
+
6
+ module Mrtable
7
+ class Table
8
+ attr_reader :rows, :header_cols
9
+
10
+ def initialize(header_cols, rows)
11
+ @header_cols = header_cols
12
+ @rows = rows
13
+ end
14
+
15
+ # ci: column index
16
+ # @return new table
17
+ def map_col_with_ci
18
+ new_rows = @rows.map { |cols|
19
+ new_cols = []
20
+ cols.each_with_index { |col, ci|
21
+ new_cols << yield(col, ci)
22
+ }
23
+ new_cols
24
+ }
25
+
26
+ new_header_cols = []
27
+ @header_cols.each_with_index { |col, ci|
28
+ new_header_cols << yield(col, ci)
29
+ }
30
+
31
+ Table.new new_header_cols, new_rows
32
+ end
33
+
34
+ def calc_maxlens
35
+ num_cols = @rows[0].size
36
+ maxlens = (0...num_cols).map { |ci|
37
+ cols_at_ci = @rows.map { |cols| cols[ci] }
38
+ if @header_cols
39
+ cols_at_ci << @header_cols[ci]
40
+ end
41
+ cols_at_ci.map { |col|
42
+ Mrtable.col_len(col)
43
+ }.max
44
+ }
45
+
46
+ # compatibility for GFM
47
+ min_len = 3
48
+ maxlens.map { |len| [len, min_len].max }
49
+ end
50
+ end
51
+
52
+ def self.int?(s)
53
+ /^\-?[\d,]+$/ =~ s
54
+ end
55
+
56
+ def self.pad_col(col, maxlen)
57
+ if int? col
58
+ pad_left col, maxlen
59
+ else
60
+ pad_right col, maxlen
61
+ end
62
+ end
63
+
64
+ def self.col_len(col)
65
+ (0...col.size).inject(0) { |sum, i|
66
+ sum + (hankaku?(col[i]) ? 1 : 2)
67
+ }
68
+ end
69
+
70
+ def self.pad_right(s, n)
71
+ rest = n - col_len(s)
72
+ if rest <= 0
73
+ return s
74
+ end
75
+ s + (" " * rest)
76
+ end
77
+
78
+ def self.pad_left(s, n)
79
+ rest = n - col_len(s)
80
+ if rest <= 0
81
+ return s
82
+ end
83
+ (" " * rest) + s
84
+ end
85
+
86
+ def self.serealize_col(col)
87
+ if col.nil?
88
+ return ""
89
+ elsif col == ""
90
+ return '""'
91
+ end
92
+
93
+ ret = json_encode(col)
94
+ if /^\s+/ =~ ret || /\s+$/ =~ ret || /^\-+$/ =~ ret
95
+ '"' + ret + '"'
96
+ else
97
+ ret.gsub("|", "\\|")
98
+ end
99
+ end
100
+
101
+ def self.to_table_row(cols)
102
+ "| " + cols.join(" | ") + " |"
103
+ end
104
+
105
+ # 32-126(0x20-0x7E), 65377-65439(0xFF61-0xFF9F)
106
+ def self.hankaku?(c)
107
+ (/^[ -~。-゚]$/ =~ c) ? true : false
108
+ end
109
+
110
+ def self.json_encode(val)
111
+ json = JSON.generate([val])
112
+ if /^\["(.*)"\]$/ =~ json
113
+ $1
114
+ elsif /^\[(.+)\]$/ =~ json
115
+ $1
116
+ else
117
+ json
118
+ end
119
+ end
120
+
121
+ def self.json_decode(str)
122
+ if /^".*"$/ =~ str
123
+ JSON.parse('[' + str + ']')[0]
124
+ else
125
+ JSON.parse('["' + str + '"]')[0]
126
+ end
127
+ end
128
+
129
+ def self.parse_col(col)
130
+ if col == ''
131
+ nil
132
+ elsif col == '""'
133
+ ""
134
+ else
135
+ json_decode(col)
136
+ end
137
+ end
138
+
139
+ def self.split_row(line)
140
+ line2 = line + " "
141
+ cols = []
142
+ buf = ""
143
+ pos = 2
144
+ pos_delta = nil
145
+
146
+ num_repeat_max = line2.size
147
+ num_repeat_max.times do
148
+ break if pos >= line2.size
149
+ pos_delta = 1
150
+ rest = line2[pos..-1]
151
+ if /^ \| / =~ rest
152
+ cols << buf; buf = ""
153
+ pos_delta = 3
154
+ elsif /^\\/ =~ rest
155
+ if rest[1] == "|"
156
+ buf += rest[1]
157
+ pos_delta = 2
158
+ else
159
+ buf += rest[0..1]
160
+ pos_delta = 2
161
+ end
162
+ else
163
+ buf += rest[0]
164
+ end
165
+ pos += pos_delta
166
+ end
167
+
168
+ cols
169
+ end
170
+
171
+ def self.parse(text)
172
+ lines = text.split(/\r?\n/)
173
+ lines2 = lines.reject { |line|
174
+ /^\s*$/ =~ line ||
175
+ /^\| \-\-\-+ \|/ =~ line
176
+ }
177
+ rows = lines2.map { |line|
178
+ split_row(line)
179
+ }
180
+ raw = Table.new rows[0], rows[1..-1]
181
+
182
+ stripped = raw.map_col_with_ci { |col, _|
183
+ col.strip
184
+ }
185
+
186
+ parsed = stripped.map_col_with_ci { |col, _|
187
+ parse_col col
188
+ }
189
+
190
+ {
191
+ :header_cols => parsed.header_cols,
192
+ :rows => parsed.rows
193
+ }
194
+ end
195
+
196
+ def self.generate(header_cols, rows)
197
+ table = Table.new(header_cols, rows)
198
+
199
+ serealized = table.map_col_with_ci { |col, _|
200
+ serealize_col col
201
+ }
202
+
203
+ maxlens = serealized.calc_maxlens()
204
+
205
+ padded = serealized.map_col_with_ci { |col, ci|
206
+ pad_col col, maxlens[ci]
207
+ }
208
+
209
+ lines = []
210
+ lines << to_table_row(padded.header_cols)
211
+ lines << to_table_row(maxlens.map { |len| "-" * len })
212
+ lines += padded.rows.map { |cols|
213
+ to_table_row(cols)
214
+ }
215
+ lines.map { |line| line + "\n" }.join("")
216
+ end
217
+ end
data/mrtable.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mrtable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mrtable"
8
+ spec.version = Mrtable::VERSION
9
+ spec.authors = ["sonota88"]
10
+ spec.email = ["yosiot8753@gmail.com"]
11
+
12
+ spec.summary = %q{machine readable table}
13
+ spec.description = %q{machine readable table}
14
+ spec.homepage = "https://github.com/sonota88/mrtable"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.13"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "minitest", "~> 5.0"
26
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mrtable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - sonota88
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: machine readable table
56
+ email:
57
+ - yosiot8753@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - README.md
65
+ - Rakefile
66
+ - bin/console
67
+ - bin/setup
68
+ - lib/mrtable.rb
69
+ - lib/mrtable/version.rb
70
+ - mrtable.gemspec
71
+ homepage: https://github.com/sonota88/mrtable
72
+ licenses: []
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.6.8
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: machine readable table
94
+ test_files: []