mindwords 0.1.0 → 0.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mindwords.rb +217 -36
- metadata +7 -7
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6221b29c92e35c56991faead9b0065df928bb5ce5664f9511ad36a41b9382e9c
|
4
|
+
data.tar.gz: 9aefdce231368e36caf338567b5b8063a12e12c5468a5bd92c7395db04ff28bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf7874e88c03ae3148102bf2ad8ecc539502c16bd620208303f54ea750262b9041de7c97b4c5bbf90b0aaf33a381f935b03be9228b1131be467c314bbd6b8344
|
7
|
+
data.tar.gz: d98408eab67356ef1312e3464ec671a381d149e7d2584ab63df6c87e4098d22c59e032dc360cd819fca2cd74d94071a5a8e400f4f87616e058f6f59a4b467c25
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mindwords.rb
CHANGED
@@ -3,32 +3,51 @@
|
|
3
3
|
# file: mindwords.rb
|
4
4
|
|
5
5
|
require 'rexle'
|
6
|
+
require 'line-tree'
|
6
7
|
|
7
|
-
|
8
|
+
module HashCopy
|
9
|
+
refine Hash do
|
10
|
+
|
11
|
+
def deep_clone()
|
12
|
+
Marshal.load(Marshal.dump(self))
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
8
17
|
|
9
|
-
|
18
|
+
class MindWords
|
19
|
+
using ColouredText
|
20
|
+
using HashCopy
|
21
|
+
|
22
|
+
|
23
|
+
def initialize(s, parent: nil, debug: false)
|
10
24
|
|
11
25
|
@debug = debug
|
12
|
-
|
13
|
-
|
26
|
+
@a = s.strip.gsub(/^\n/,'').lines
|
27
|
+
@a.shift if @a.first =~ /<\?mindwords\?>/
|
28
|
+
|
29
|
+
lines = @a.map do |line|
|
14
30
|
|
15
31
|
word = line.split(/ (?=#)/,2)
|
16
32
|
|
17
33
|
end
|
18
|
-
|
34
|
+
|
19
35
|
h = {}
|
36
|
+
@hashtags = {}
|
20
37
|
|
21
|
-
lines.each do |
|
38
|
+
lines.each do |title, rawtags|
|
22
39
|
|
23
|
-
|
40
|
+
rawtags.scan(/#(\w+)/).flatten(1).each do |rawtag|
|
24
41
|
tag = rawtag.gsub(/ +/, '_')
|
25
42
|
h[tag] ||= []
|
26
|
-
h[tag] <<
|
43
|
+
h[tag] << title
|
27
44
|
end
|
28
45
|
|
29
46
|
end
|
47
|
+
|
48
|
+
@hashtags = h.deep_clone.sort.map {|tag, fields| [tag, fields.sort]}.to_h
|
30
49
|
|
31
|
-
# does the key exist as a field?
|
50
|
+
# does the key exist as a field? Nesting of hash object is performed here.
|
32
51
|
|
33
52
|
h.keys.each do |key|
|
34
53
|
|
@@ -41,30 +60,16 @@ class MindWords
|
|
41
60
|
|
42
61
|
end
|
43
62
|
|
63
|
+
@h = h
|
64
|
+
|
44
65
|
a = rexlize(h)
|
45
66
|
doc = Rexle.new(['root', {}, '', *a])
|
46
67
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
next if rows.length < 2
|
53
|
-
|
54
|
-
rows[1..-1].each do |e2|
|
55
|
-
puts 'e2: ' + e2.name.inspect if @debug
|
56
|
-
duplicates << [e.backtrack.to_s, e2.backtrack.to_s] #unless e2.has_elements?
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
duplicates.each do |path, oldpath|
|
61
|
-
e = doc.element(path);
|
62
|
-
e2 = doc.element(oldpath);
|
63
|
-
e2.parent.add e
|
64
|
-
e2.delete
|
65
|
-
end
|
66
|
-
|
67
|
-
# remove redundant nodes
|
68
|
+
|
69
|
+
# remove duplicates which appear in the same branch above the nested node
|
70
|
+
rm_duplicates(doc)
|
71
|
+
|
72
|
+
# remove redundant nodes (outsiders)
|
68
73
|
# a redundant node is where all children exist in existing nested nodes
|
69
74
|
|
70
75
|
redundants = doc.root.elements.map do |e|
|
@@ -78,13 +83,138 @@ class MindWords
|
|
78
83
|
end
|
79
84
|
|
80
85
|
redundants.compact.each {|x| doc.element(x).delete }
|
86
|
+
rm_duplicates(doc)
|
87
|
+
|
88
|
+
node = if parent then
|
89
|
+
found = doc.root.element('//' + parent)
|
90
|
+
found ? found : doc.root
|
91
|
+
else
|
92
|
+
doc.root
|
93
|
+
end
|
94
|
+
|
95
|
+
@outline = treeize node
|
96
|
+
|
97
|
+
node.root.each_recursive do |e|
|
98
|
+
|
99
|
+
e.attributes[:id] = e.attributes[:title].downcase.gsub(/ +/,'-')
|
100
|
+
|
101
|
+
s = e.parent.attributes[:breadcrumb] ? \
|
102
|
+
e.parent.attributes[:breadcrumb].to_s + ' / ' : ''
|
103
|
+
e.attributes[:breadcrumb] = s + e.value.strip
|
104
|
+
|
105
|
+
r = @a.grep(/^#{e.attributes[:title]} #/i)
|
106
|
+
next unless r.any?
|
107
|
+
e.attributes[:hashtags] = r[0].scan(/(?<=#)\w+/).join(' ')
|
108
|
+
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
@xml = node.xml pretty: true
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def element(id)
|
117
|
+
|
118
|
+
doc = Rexle.new(@xml)
|
119
|
+
e = doc.root.element("//*[@id='#{id}']")
|
120
|
+
#e.attributes[:breadcrumb].to_s if e
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
def search(keyword)
|
125
|
+
|
126
|
+
a = @a.grep(/#{keyword}/i).map do |line|
|
127
|
+
|
128
|
+
puts 'line: ' + line.inspect if @debug
|
129
|
+
|
130
|
+
words = line.split
|
131
|
+
r = words.grep /#{keyword}/i
|
132
|
+
i = words.index r[0]
|
133
|
+
|
134
|
+
[line, i]
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
return nil if a.empty?
|
139
|
+
#return a[0][0] if a.length < 2
|
81
140
|
|
82
|
-
|
141
|
+
a2 = a.sort_by(&:last).map(&:first)
|
142
|
+
puts 'a2: ' + a2.inspect if @debug
|
143
|
+
MindWords.new(a2.join, parent: keyword, debug: @debug)
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
def sort()
|
148
|
+
s = @a.sort.join
|
149
|
+
|
150
|
+
def s.to_s()
|
151
|
+
self.lines.map do |x|
|
152
|
+
title, hashtags = x.split(/(?=#)/,2)
|
153
|
+
title + hashtags.chomp.brown
|
154
|
+
end.join("\n")
|
155
|
+
end
|
156
|
+
|
157
|
+
return s
|
158
|
+
end
|
159
|
+
|
160
|
+
def sort!()
|
161
|
+
@a = sort().lines
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
165
|
+
def tag_sort()
|
166
|
+
|
167
|
+
h = @a.group_by {|x| x[/#\w+/]}
|
168
|
+
s = h.sort.map {|key, value| value.sort }.join
|
169
|
+
|
170
|
+
def s.to_s()
|
171
|
+
self.lines.map do |x|
|
172
|
+
title, hashtags = x.split(/(?=#)/,2)
|
173
|
+
title + hashtags.chomp.brown
|
174
|
+
end.join("\n")
|
175
|
+
end
|
176
|
+
|
177
|
+
return s
|
83
178
|
|
84
179
|
end
|
180
|
+
|
181
|
+
def tag_sort!()
|
182
|
+
@a = tag_sort().lines
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
def to_h()
|
187
|
+
@h
|
188
|
+
end
|
189
|
+
|
190
|
+
def to_hashtags()
|
191
|
+
@hashtags
|
192
|
+
end
|
85
193
|
|
86
|
-
def to_outline()
|
87
|
-
@outline
|
194
|
+
def to_outline(sort: true)
|
195
|
+
sort ? a2tree(tree_sort(LineTree.new(@outline).to_a)) : @outline
|
196
|
+
end
|
197
|
+
|
198
|
+
def to_s(colour: false)
|
199
|
+
|
200
|
+
header = "<?mindwords?>\n\n"
|
201
|
+
return header + @a.join unless colour
|
202
|
+
|
203
|
+
body = @a.map do |x|
|
204
|
+
title, hashtags = x.split(/(?=#)/,2)
|
205
|
+
title + hashtags.chomp.brown
|
206
|
+
end.join("\n")
|
207
|
+
|
208
|
+
header + body
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
def to_words()
|
213
|
+
to_outline.lines.map {|x| x[/\w[\w ]+/] }
|
214
|
+
end
|
215
|
+
|
216
|
+
def to_xml()
|
217
|
+
@xml
|
88
218
|
end
|
89
219
|
|
90
220
|
private
|
@@ -97,15 +227,45 @@ class MindWords
|
|
97
227
|
|
98
228
|
case x
|
99
229
|
when String
|
100
|
-
[x.gsub(/ +/,'_'), {}, x]
|
230
|
+
[x.gsub(/ +/,'_'), {title: x}, x]
|
101
231
|
when Hash
|
102
|
-
[
|
232
|
+
[
|
233
|
+
x.keys.first.gsub(/_/,' '),
|
234
|
+
{title: x.keys.first},
|
235
|
+
x.keys.first,
|
236
|
+
*rexlize(x.values.first)
|
237
|
+
]
|
103
238
|
when Array
|
104
|
-
[x.first
|
239
|
+
[x.first.gsub(/_/,' '), {title: x.first}, x.first, *rexlize(x.last)]
|
105
240
|
end
|
106
241
|
end
|
107
242
|
|
108
243
|
end
|
244
|
+
|
245
|
+
def rm_duplicates(doc)
|
246
|
+
|
247
|
+
duplicates = []
|
248
|
+
doc.root.each_recursive do |e|
|
249
|
+
|
250
|
+
puts 'e: ' + e.name.inspect if @debug
|
251
|
+
rows = e.parent.xpath('//' + e.name)
|
252
|
+
next if rows.length < 2
|
253
|
+
|
254
|
+
rows[1..-1].each do |e2|
|
255
|
+
puts 'e2: ' + e2.name.inspect if @debug
|
256
|
+
duplicates << [e.backtrack.to_s, e2.backtrack.to_s]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
duplicates.each do |path, oldpath|
|
261
|
+
e = doc.element(path);
|
262
|
+
e2 = doc.element(oldpath);
|
263
|
+
next unless e2
|
264
|
+
e2.parent.add e
|
265
|
+
e2.delete
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
109
269
|
|
110
270
|
def treeize(node, indent=0)
|
111
271
|
|
@@ -121,6 +281,27 @@ class MindWords
|
|
121
281
|
|
122
282
|
lines.join
|
123
283
|
end
|
284
|
+
|
285
|
+
def tree_sort(a)
|
286
|
+
|
287
|
+
if a.first.is_a? Array then
|
288
|
+
a.sort_by(&:first).map {|x| tree_sort(x) }
|
289
|
+
elsif a.any?
|
290
|
+
[a.first] + tree_sort(a[1..-1])
|
291
|
+
else
|
292
|
+
[]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def a2tree(a, indent=0)
|
297
|
+
|
298
|
+
a.map do |row|
|
299
|
+
title, *remaining = row
|
300
|
+
children = remaining ? a2tree(remaining, indent+1) : ''
|
301
|
+
(' ' * indent) + title + "\n" + children
|
302
|
+
end.join
|
303
|
+
|
304
|
+
end
|
124
305
|
|
125
306
|
end
|
126
307
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mindwords
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,28 +35,28 @@ cert_chain:
|
|
35
35
|
aWH7D2AmhOpqNwWnPHzWR/yzpigAVTrvpHfRxZleQj6Z/090nIH2KR0RdioMmPFq
|
36
36
|
3+574KQzs/gR9Y5a+iMcvHRN
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2021-01-
|
38
|
+
date: 2021-01-20 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: line-tree
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '0.9'
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 0.9.1
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '0.9'
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
59
|
+
version: 0.9.1
|
60
60
|
description:
|
61
61
|
email: digital.robertson@gmail.com
|
62
62
|
executables: []
|
metadata.gz.sig
CHANGED
Binary file
|