analy_z 0.1.5 → 0.1.6
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/README.md +52 -5
- data/lib/analy_z/html/word_val.rb +179 -0
- data/lib/analy_z/html.rb +19 -0
- data/lib/analy_z/version.rb +1 -1
- data/lib/analy_z.rb +9 -179
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df13178fbd1dcad7f742f0276f16afaa8fd1097a
|
4
|
+
data.tar.gz: 18409354de2247a9f98721b7c5ab64384419f6c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed74cb9fe090d407a18ece87f5e84dfea9178c5825cbbb34f2340f3b6b16de2dec23dad566760c14b446126294e8bf3816ad80e4ebac2fe6607001d195925c10
|
7
|
+
data.tar.gz: b875b6ca63249366070cfbf74b60b24c8ba42c868493ba26a516d70f737e272fa1b0637f6a0d77d85b1ea9a6104c603f591c9ac45bc28f7732575a84c55d2aca
|
data/README.md
CHANGED
@@ -1,8 +1,34 @@
|
|
1
1
|
# AnalyZ
|
2
2
|
|
3
|
-
|
3
|
+
This is gem for text analyze.
|
4
|
+
Now you can analyze hse-tf-idf value about each words.
|
4
5
|
|
5
|
-
|
6
|
+
## What is hse-tf-idf
|
7
|
+
|
8
|
+
hse-tf-idf = hse * tf-idf
|
9
|
+
|
10
|
+
### What is hse
|
11
|
+
|
12
|
+
Hse is HTML Semantic Element (valuation).
|
13
|
+
Evaluate HTML tag and express it's value in number.
|
14
|
+
|
15
|
+
for example
|
16
|
+
|
17
|
+
| tag name | font-size | font-weight | valuation |
|
18
|
+
|:----------:|:-----------:|:------------:|:----------:|
|
19
|
+
| h1 | 2 | 1.75 | 3.5 |
|
20
|
+
| h2 | 1.5 | 1.75 | 2.625 |
|
21
|
+
| h3 | 1.17 | 1.75 | 2.0475 |
|
22
|
+
| h4 | 1 | 1.75 | 1.75 |
|
23
|
+
|
24
|
+
`valuation = font-size * font-weight`
|
25
|
+
|
26
|
+
And I'm looking for another valuation.
|
27
|
+
Please tell me if you find out more good tag or style.
|
28
|
+
|
29
|
+
I want to add hse valuation logic below,
|
30
|
+
- font size by css
|
31
|
+
- font color
|
6
32
|
|
7
33
|
## Installation
|
8
34
|
|
@@ -14,15 +40,36 @@ gem 'analy_z'
|
|
14
40
|
|
15
41
|
And then execute:
|
16
42
|
|
17
|
-
$ bundle
|
43
|
+
$ bundle install
|
18
44
|
|
19
45
|
Or install it yourself as:
|
20
46
|
|
21
47
|
$ gem install analy_z
|
22
48
|
|
49
|
+
|
23
50
|
## Usage
|
24
51
|
|
25
|
-
|
52
|
+
```ruby
|
53
|
+
require 'analy_z'
|
54
|
+
|
55
|
+
# file_path : file path for files you want to analyze
|
56
|
+
# for example 'html/*.html'
|
57
|
+
# NOTE please add more than 2 files
|
58
|
+
# because only 1 file, analy_z can't calucurate idf
|
59
|
+
# selector : selector for place you want to analyze
|
60
|
+
# for example '#main .content'
|
61
|
+
|
62
|
+
a = AnalyZ::HTML.word_val(file_path, selector)
|
63
|
+
|
64
|
+
a.tf # tf
|
65
|
+
a.idf # idf
|
66
|
+
a.tf_idf # tf-idf
|
67
|
+
a.hse_tf_idf # hse-tf-idf
|
68
|
+
a.words # words analy_z analyzed
|
69
|
+
a.texts # texts analy_z analyzed
|
70
|
+
a.sentences # sentences analy_z analyzed
|
71
|
+
|
72
|
+
```
|
26
73
|
|
27
74
|
## Development
|
28
75
|
|
@@ -32,7 +79,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
79
|
|
33
80
|
## Contributing
|
34
81
|
|
35
|
-
1. Fork it ( https://github.com/
|
82
|
+
1. Fork it ( https://github.com/nao215/analy_z/fork )
|
36
83
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
84
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
85
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module AnalyZ
|
2
|
+
|
3
|
+
module HTML
|
4
|
+
|
5
|
+
class WordVal
|
6
|
+
|
7
|
+
attr_accessor :tf
|
8
|
+
attr_accessor :idf
|
9
|
+
attr_accessor :tf_idf
|
10
|
+
attr_accessor :hse_tf_idf
|
11
|
+
attr_accessor :words
|
12
|
+
attr_accessor :texts
|
13
|
+
attr_accessor :sentences
|
14
|
+
|
15
|
+
def initialize html_path, selector = 'body', type_ary = ['名詞']
|
16
|
+
@sentences = {}
|
17
|
+
Dir.glob(html_path).each do |f|
|
18
|
+
print '.'
|
19
|
+
@sentences[f] = parse_html(Nokogiri::HTML.parse(File.read(f), nil, nil).css(selector).to_html)
|
20
|
+
end
|
21
|
+
|
22
|
+
puts "\n=== creating sentences file ==="
|
23
|
+
txt = ""
|
24
|
+
@sentences.each do |k, sentences|
|
25
|
+
print '.'
|
26
|
+
txt << sentences.map{|s| s[0] }.join + '/=== EOS ===/'
|
27
|
+
end
|
28
|
+
|
29
|
+
FileUtils.mkdir_p('tmp') unless FileTest.exist?('tmp')
|
30
|
+
text_file_path = "tmp/#{DateTime.now}.txt"
|
31
|
+
File.write(text_file_path, txt)
|
32
|
+
|
33
|
+
puts "\n=== analyzing... ==="
|
34
|
+
analyze_words(@sentences, text_file_path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def analyze_words sentences, text_file_path, type_ary = ['名詞']
|
38
|
+
|
39
|
+
@words, @tf, @idf, @hse = {}, {}, {}, {}
|
40
|
+
|
41
|
+
puts "=== calculating tf and idf and hse ==="
|
42
|
+
sentences.each do |key, sentence_ary|
|
43
|
+
print '.'
|
44
|
+
text = sentence_ary.map {|s| s[0] }.join
|
45
|
+
@words[key] = parse_by_natto(text, type_ary)
|
46
|
+
@tf[key] = calc_tf(@words[key])
|
47
|
+
@idf[key] = calc_idf(@words[key], text_file_path)
|
48
|
+
@hse[key] = calc_hse(@words[key], sentence_ary)
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "\n=== calculating tf idf ==="
|
52
|
+
@tf_idf = calc_tf_idf(@tf, @idf)
|
53
|
+
|
54
|
+
puts "=== calculating hse tf idf ==="
|
55
|
+
@hse_tf_idf = calc_hse_tf_idf(@tf_idf, @hse)
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_html html
|
60
|
+
sentences, important_tags = [], []
|
61
|
+
tag_rep = /<(".*?"|'.*?'|[^'"])*?>/
|
62
|
+
h_tag_reg = /<[hH][1-4].*?>.*?<\/[hH][1-4]>/
|
63
|
+
|
64
|
+
important_tags = html.scan(h_tag_reg)
|
65
|
+
.map{|m| [m.gsub(/<(".*?"|'.*?'|[^'"])*?>/, ''), m.match(/[hH][1-4]/)[0] ]}
|
66
|
+
|
67
|
+
sentences = html.gsub(/\"/, '')
|
68
|
+
.split(tag_rep)
|
69
|
+
.delete_if{|el| el != ['h1', 'h2', 'h3', 'h4'] && el =~ /\s/ || el.length <= 1}
|
70
|
+
.map{|m| [m, 1]}
|
71
|
+
|
72
|
+
sentences.each_with_index do |sentence, i|
|
73
|
+
important_tags.each do |tag_data|
|
74
|
+
rate = 2 * 1.75 if tag_data[1] == 'h1'
|
75
|
+
rate = 1.5 * 1.75 if tag_data[1] == 'h2'
|
76
|
+
rate = 1.17 * 1.75 if tag_data[1] == 'h3'
|
77
|
+
rate = 1.17 * 1.75 if tag_data[1] == 'h4'
|
78
|
+
sentences[i][1] = rate if sentence[0].include?(tag_data[0]) || tag_data[0].include?(sentence[0])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
sentences
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_by_natto text, type_ary
|
87
|
+
words = []
|
88
|
+
|
89
|
+
Natto::MeCab.new.parse(text).split(/\n/).map do |row|
|
90
|
+
row = row.split(/\t|,/)
|
91
|
+
words << row[0] if type_ary.include?(row[1]) # row[0] is word, row[1] is a part of speech
|
92
|
+
end
|
93
|
+
|
94
|
+
words
|
95
|
+
end
|
96
|
+
|
97
|
+
def calc_tf words
|
98
|
+
freq_hash = {}
|
99
|
+
|
100
|
+
words.each_with_index do |word, i|
|
101
|
+
freq_hash[word] = freq_hash.has_key?(word) ? freq_hash[word] + 1 : 1
|
102
|
+
end
|
103
|
+
|
104
|
+
tf_list = freq_hash.sort_by {|k, v| v }.reverse.map do |k, v|
|
105
|
+
[k, v / words.length.to_f]
|
106
|
+
end
|
107
|
+
|
108
|
+
tf_list
|
109
|
+
end
|
110
|
+
|
111
|
+
def standardization_tf tf_ary_list, ave_word_num
|
112
|
+
return tf_ary_list.map do |tf_ary|
|
113
|
+
tf_ary.map do |tf|
|
114
|
+
[tf[0], tf[1] * (tf_ary.length / ave_word_num.to_f), tf_ary.length / ave_word_num.to_f]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def calc_idf words, text_file_path
|
120
|
+
texts = File.read(text_file_path).split('/=== EOS ===/')
|
121
|
+
words.map do |word|
|
122
|
+
cnt = 0
|
123
|
+
texts.each do |text|
|
124
|
+
cnt += 1 if text.include?(word)
|
125
|
+
end
|
126
|
+
[word, Math.log(sentences.length / cnt.to_f)]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def calc_hse words, sentence_ary
|
131
|
+
sentence_ary = sentence_ary.select{|sentence| sentence[1] != 1}
|
132
|
+
words.map do |word|
|
133
|
+
rate = 1
|
134
|
+
sentence_ary.each do |sentence|
|
135
|
+
rate = sentence[1] if sentence[0].include?(word[0])
|
136
|
+
end
|
137
|
+
[word, rate]
|
138
|
+
end.uniq
|
139
|
+
end
|
140
|
+
|
141
|
+
def calc_tf_idf tf_list_hash, idf_list_hash
|
142
|
+
|
143
|
+
tf_idfs = {}
|
144
|
+
|
145
|
+
tf_list_hash.each do |k, tf|
|
146
|
+
tf_idf = []
|
147
|
+
idf_list_hash[k].each do |idf|
|
148
|
+
tf_idf << [idf[0], idf[1] * tf.assoc(idf[0])[1]]
|
149
|
+
end
|
150
|
+
tf_idfs[k] = tf_idf.sort{ |a, b| b[1] <=> a[1] }.uniq
|
151
|
+
end
|
152
|
+
|
153
|
+
tf_idfs
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
def calc_hse_tf_idf tf_idf_list_hash, hse
|
158
|
+
|
159
|
+
hse_tf_idf = {}
|
160
|
+
|
161
|
+
hse.each do |k, h|
|
162
|
+
hse[k] = hse[k].select {|h| h[1] != 1 }
|
163
|
+
end
|
164
|
+
|
165
|
+
tf_idf_list_hash.each do |k, tf_idf_list|
|
166
|
+
hse_tf_idf[k] = tf_idf_list.map do |tf_idf|
|
167
|
+
rate = hse[k].assoc(tf_idf[0]) ? hse[k].assoc(tf_idf[0])[1] : 1
|
168
|
+
[tf_idf[0], tf_idf[1] * rate]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
hse_tf_idf
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
data/lib/analy_z/html.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module AnalyZ
|
2
|
+
|
3
|
+
class << self
|
4
|
+
def HTML html_path, selector = 'body', type_ary = ['名詞']
|
5
|
+
AnalyZ::HTML
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
module HTML
|
11
|
+
|
12
|
+
def self.word_val html_path, selector = 'body', type_ary = ['名詞']
|
13
|
+
WordVal.new(html_path, selector, type_ary)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
data/lib/analy_z/version.rb
CHANGED
data/lib/analy_z.rb
CHANGED
@@ -1,183 +1,13 @@
|
|
1
1
|
require "analy_z/version"
|
2
|
+
require 'pp'
|
3
|
+
require 'date'
|
4
|
+
require 'natto'
|
5
|
+
require 'nokogiri'
|
6
|
+
require 'fileutils'
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require 'pp'
|
8
|
-
require 'date'
|
9
|
-
require 'natto'
|
10
|
-
require 'nokogiri'
|
11
|
-
require 'fileutils'
|
12
|
-
|
13
|
-
attr_accessor :tf
|
14
|
-
attr_accessor :idf
|
15
|
-
attr_accessor :tf_idf
|
16
|
-
attr_accessor :hse_tf_idf
|
17
|
-
attr_accessor :words
|
18
|
-
attr_accessor :texts
|
19
|
-
attr_accessor :sentences
|
20
|
-
|
21
|
-
def initialize html_path, selector = 'body', type_ary = ['名詞']
|
22
|
-
@sentences = {}
|
23
|
-
Dir.glob(html_path).each do |f|
|
24
|
-
print '.'
|
25
|
-
@sentences[f] = parse_html(Nokogiri::HTML.parse(File.read(f), nil, nil).css(selector).to_html)
|
26
|
-
end
|
27
|
-
|
28
|
-
puts "\n=== creating sentences file ==="
|
29
|
-
txt = ""
|
30
|
-
@sentences.each do |k, sentences|
|
31
|
-
print '.'
|
32
|
-
txt << sentences.map{|s| s[0] }.join + '/=== EOS ===/'
|
33
|
-
end
|
34
|
-
|
35
|
-
FileUtils.mkdir_p('tmp') unless FileTest.exist?('tmp')
|
36
|
-
text_file_path = "tmp/#{DateTime.now}.txt"
|
37
|
-
File.write(text_file_path, txt)
|
38
|
-
|
39
|
-
puts "\n=== analyzing... ==="
|
40
|
-
analyze_words(@sentences, text_file_path)
|
41
|
-
end
|
42
|
-
|
43
|
-
def analyze_words sentences, text_file_path, type_ary = ['名詞']
|
44
|
-
|
45
|
-
@words, @tf, @idf, @hse = {}, {}, {}, {}
|
46
|
-
|
47
|
-
puts "=== calculating tf and idf and hse ==="
|
48
|
-
sentences.each do |key, sentence_ary|
|
49
|
-
print '.'
|
50
|
-
text = sentence_ary.map {|s| s[0] }.join
|
51
|
-
@words[key] = parse_by_natto(text, type_ary)
|
52
|
-
@tf[key] = calc_tf(@words[key])
|
53
|
-
@idf[key] = calc_idf(@words[key], text_file_path)
|
54
|
-
@hse[key] = calc_hse(@words[key], sentence_ary)
|
55
|
-
end
|
56
|
-
|
57
|
-
puts "\n=== calculating tf idf ==="
|
58
|
-
@tf_idf = calc_tf_idf(@tf, @idf)
|
59
|
-
|
60
|
-
puts "=== calculating hse tf idf ==="
|
61
|
-
@hse_tf_idf = calc_hse_tf_idf(@tf_idf, @hse)
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
def parse_html html
|
66
|
-
sentences, important_tags = [], []
|
67
|
-
tag_rep = /<(".*?"|'.*?'|[^'"])*?>/
|
68
|
-
h_tag_reg = /<[hH][1-4].*?>.*?<\/[hH][1-4]>/
|
69
|
-
|
70
|
-
important_tags = html.scan(h_tag_reg)
|
71
|
-
.map{|m| [m.gsub(/<(".*?"|'.*?'|[^'"])*?>/, ''), m.match(/[hH][1-4]/)[0] ]}
|
72
|
-
|
73
|
-
sentences = html.gsub(/\"/, '')
|
74
|
-
.split(tag_rep)
|
75
|
-
.delete_if{|el| el != ['h1', 'h2', 'h3', 'h4'] && el =~ /\s/ || el.length <= 1}
|
76
|
-
.map{|m| [m, 1]}
|
77
|
-
|
78
|
-
sentences.each_with_index do |sentence, i|
|
79
|
-
important_tags.each do |tag_data|
|
80
|
-
rate = 2 * 1.75 if tag_data[1] == 'h1'
|
81
|
-
rate = 1.5 * 1.75 if tag_data[1] == 'h2'
|
82
|
-
rate = 1.17 * 1.75 if tag_data[1] == 'h3'
|
83
|
-
rate = 1.17 * 1.75 if tag_data[1] == 'h4'
|
84
|
-
sentences[i][1] = rate if sentence[0].include?(tag_data[0]) || tag_data[0].include?(sentence[0])
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
sentences
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
def parse_by_natto text, type_ary
|
93
|
-
words = []
|
94
|
-
|
95
|
-
Natto::MeCab.new.parse(text).split(/\n/).map do |row|
|
96
|
-
row = row.split(/\t|,/)
|
97
|
-
words << row[0] if type_ary.include?(row[1]) # row[0] is word, row[1] is a part of speech
|
98
|
-
end
|
99
|
-
|
100
|
-
words
|
101
|
-
end
|
102
|
-
|
103
|
-
def calc_tf words
|
104
|
-
freq_hash = {}
|
105
|
-
|
106
|
-
words.each_with_index do |word, i|
|
107
|
-
freq_hash[word] = freq_hash.has_key?(word) ? freq_hash[word] + 1 : 1
|
108
|
-
end
|
109
|
-
|
110
|
-
tf_list = freq_hash.sort_by {|k, v| v }.reverse.map do |k, v|
|
111
|
-
[k, v / words.length.to_f]
|
112
|
-
end
|
113
|
-
|
114
|
-
tf_list
|
115
|
-
end
|
116
|
-
|
117
|
-
def standardization_tf tf_ary_list, ave_word_num
|
118
|
-
return tf_ary_list.map do |tf_ary|
|
119
|
-
tf_ary.map do |tf|
|
120
|
-
[tf[0], tf[1] * (tf_ary.length / ave_word_num.to_f), tf_ary.length / ave_word_num.to_f]
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def calc_idf words, text_file_path
|
126
|
-
texts = File.read(text_file_path).split('/=== EOS ===/')
|
127
|
-
words.map do |word|
|
128
|
-
cnt = 0
|
129
|
-
texts.each do |text|
|
130
|
-
cnt += 1 if text.include?(word)
|
131
|
-
end
|
132
|
-
[word, Math.log(sentences.length / cnt.to_f)]
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def calc_hse words, sentence_ary
|
137
|
-
sentence_ary = sentence_ary.select{|sentence| sentence[1] != 1}
|
138
|
-
words.map do |word|
|
139
|
-
rate = 1
|
140
|
-
sentence_ary.each do |sentence|
|
141
|
-
rate = sentence[1] if sentence[0].include?(word[0])
|
142
|
-
end
|
143
|
-
[word, rate]
|
144
|
-
end.uniq
|
145
|
-
end
|
146
|
-
|
147
|
-
def calc_tf_idf tf_list_hash, idf_list_hash
|
148
|
-
|
149
|
-
tf_idfs = {}
|
150
|
-
|
151
|
-
tf_list_hash.each do |k, tf|
|
152
|
-
tf_idf = []
|
153
|
-
idf_list_hash[k].each do |idf|
|
154
|
-
tf_idf << [idf[0], idf[1] * tf.assoc(idf[0])[1]]
|
155
|
-
end
|
156
|
-
tf_idfs[k] = tf_idf.sort{ |a, b| b[1] <=> a[1] }.uniq
|
157
|
-
end
|
158
|
-
|
159
|
-
tf_idfs
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
def calc_hse_tf_idf tf_idf_list_hash, hse
|
164
|
-
|
165
|
-
hse_tf_idf = {}
|
166
|
-
|
167
|
-
hse.each do |k, h|
|
168
|
-
hse[k] = hse[k].select {|h| h[1] != 1 }
|
169
|
-
end
|
170
|
-
|
171
|
-
tf_idf_list_hash.each do |k, tf_idf_list|
|
172
|
-
hse_tf_idf[k] = tf_idf_list.map do |tf_idf|
|
173
|
-
rate = hse[k].assoc(tf_idf[0]) ? hse[k].assoc(tf_idf[0])[1] : 1
|
174
|
-
[tf_idf[0], tf_idf[1] * rate]
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
hse_tf_idf
|
179
|
-
end
|
180
|
-
|
181
|
-
end
|
8
|
+
require 'analy_z/html'
|
9
|
+
require 'analy_z/html/word_val'
|
10
|
+
require 'analy_z/html/similarity'
|
182
11
|
|
12
|
+
module AnalyZ
|
183
13
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: analy_z
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nao215
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04
|
11
|
+
date: 2016-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: natto
|
@@ -69,6 +69,8 @@ files:
|
|
69
69
|
- bin/console
|
70
70
|
- bin/setup
|
71
71
|
- lib/analy_z.rb
|
72
|
+
- lib/analy_z/html.rb
|
73
|
+
- lib/analy_z/html/word_val.rb
|
72
74
|
- lib/analy_z/version.rb
|
73
75
|
homepage: ''
|
74
76
|
licenses: []
|